I have a large MYSQL / PHP in a while loop report being run and in many cases the report times out due to the large amount of data being calculated.

Is there a way to make have a div displaying "Processing" when the while loops is calculating and if the report is completed , a div "complete" is displayed.

For example: The calculation are not complete because the variable $totals are not displayed. It is only when $Total is a rational value then "Completed" is displayed.

Many Thanks in advance!

<?php
    session_start();
?>
<html>
<body id="dt_example">
<div "Processing">
<?php
    while($noticia = mysql_fetch_array($query)) { // Very long mysql query , query usually times out in this loop. Div "Processing" shown
        $Total +=$subtotal;
    }

    echo "Totals: ".$Total; //when this is executed , the report is succesful and div "Completed " is displayed
    echo "<div Completed>";

?></tbody></table></div>
</body>
</html>

Dani AI

Generated

Short summary and practical next steps building on suggestions from , and : the robust way is to let the long work run server-side and report progress to the browser (polling or push) instead of trying to keep one PHP request both doing all the work and driving the UI. Releasing the PHP session lock early is important in that flow because a session left open will block your browser's progress calls. (php.net)

A simple, reliable pattern: have the worker script write progress (0–100) to a temporary place (DB, Redis, or a file keyed by a token). Call session_write_close() before the long loop so the progress-check requests can run in parallel. Expose a small progress API that returns JSON; the client polls it every second and swaps the “Processing” div to “Complete” when progress hits 100. Example (very small sketch):

// worker.php (after preparing a token)
session_write_close();
file_put_contents("/tmp/prog_$token", "0");
while(fetchRow()) {
  // expensive work...
  file_put_contents("/tmp/prog_$token", (int)($i/$total*100));
}
file_put_contents("/tmp/prog_$token", "100");
// client polling
setInterval(async ()=> {
  let r = await fetch('/progress.php?token=abc');
  let p = await r.json();
  document.getElementById('status').textContent = p.progress==100?'Complete':'Processing';
},1000);

Server-push via Server-Sent Events (EventSource) is a cleaner alternative if you want one-way streaming of progress without polling; it’s widely supported and simple to implement on the client. (developer.mozilla.org)

If you try to stream HTML directly (echo + ob_flush() + flush()) be aware PHP and web servers can buffer and browsers may not render partial <table> output until the table is closed — that’s why many people stream JSON lines and let client JS append rows. See PHP’s notes on flushing and incremental rendering behavior. (php.net)

Finally, for long scripts check PHP execution limits (or move the job to a background worker/queue) so it won't be killed mid-run. set_time_limit() helps but server/webserver timeouts also apply. (php.net)

Troubleshooting tips: verify file/DB permissions for the progress store, disable compression or server buffering if you need immediate flushes, and test with small datasets first so you can confirm the UI updates as expected.

Recommended Answers

All 3 Replies

First of all, mysql_* has been depreciated, consider using pdo/mysqli_*
Based on the situation, I will probably using ajax to retrieve the data for time consuming data. Example, I will start with the div with "loading data...", then when data finished loaded using ajax, simply replace the content of that div. If the data context is too large, I will even break the queries into part(example by pages/limit).

In addition to everything says, can you have sql do some of the work in calculating the results you need? You show $total which could likely be calculated from a sql query using aggregate functions like SUM(), etc. MySQL is often much better optimized for generating totals than doing it via PHP.

You should switch from using table to using divs.

When you use a table the browser doesn't show the table until it gets to the </table> tag. If you use divs as soon as one record is parsed from mysql you get it shown on your website.

You can also set_time_limit(0) while you are generating this so it doesn't time out.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.