PHP AJAX handler to fill an HTML table I would like to know if this code follows recommended practices and standards for AJAX/PHP calls. Can this AJAX + PHP code be improved in terms of security, performance, etc.?

ajax.js:

function getTableData() {
    const xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
        if (this.readyState === 4 &amp;&amp; this.status === 200) {
            document.querySelector('#test-table tbody').innerHTML = this.responseText;
        }
    }
    xmlhttp.open('GET', 'ajax.php', true);
    xmlhttp.send();
}

$(document).ready(function () {
    getTableData();
});


ajax.php:

&lt;?php
$data = prepareDataForTable();
$data_length = count($data);
$columns = 4;

for ($row = 0; $row &lt; $data_length; $row += $columns) {
    echo '&lt;tr&gt;';
        for ($col = 0; $col &lt; $columns &amp;&amp; ($col + $row) &lt; $data_length; $col++) {
            echo '&lt;td&gt;' . $data[$col + $row] . '&lt;/td&gt;';
        }
    echo '&lt;/tr&gt;';
}
?&gt;


ajax.html:

&lt;table id="test-table"&gt;
    &lt;tbody&gt;
    &lt;/tbody&gt;
&lt;/table&gt;


I specifically want to know if this is a good way to send information back to the client - by running loops and echoing output.
Trying to follow your mathematical loop conditions makes my eyes go crossed in a hurry.

Perhaps you'd entertain a less-math-heavy alternative:

foreach (array_chunk($array, 4) as $row) {
    echo '&lt;tr&gt;&lt;td&gt;' , implode('&lt;/td&gt;&lt;td&gt;', $row) , '&lt;/td&gt;' , str_repeat('&lt;td&gt;&lt;/td&gt;', 4-count($row)) , '&lt;/tr&gt;';
}


Granted this will be making a no-output call of str_repeat() on all rows except potentially the final row, but I think this technique will be more developer friendly.  I'm assuming that I understand your $data (Demo).  I could have written a conditional for str_repeat() but felt that would only bloat the code.

I tend to lean toward passing json back from an ajax call, but for this situation sending back html is the simpler approach.