I've found sample code here :
http://board.phpbuilder.com/showthread.php?10306202-RESOLVED-Progress-Bar-for-a-system-call

Which uses multiple ob_flush() & flush() commands :

$display_block1 = "code for the JavaScript progress bar";
$display_block2 = "code to turn off the bar";
echo $display_block;
ob_flush();
flush();
system($cmd)
echo $display_block2;
ob_flush();
flush();

I've started to expand on this and when a system command is run I update the screen with progress.
This means I have lots of ob_flush() & flush() commands in my script.

Whilst it is working as I want, will this cause any issues ? is it a bad thing to do ?

Thanks 🙂

    Seems to me like it would be better to use some background AJAX request to handle this instead.

      Thanks for your reply.

      Could you point me in the right direction ?

        First off, the original approach requires that you output enough characters to fill the webserver output buffer which is independent from the PHP output buffer.

        As for the js XHR approach, assuming you use jQuery, which you should.

        
        <div id="system_call_info">
        </div>
        <script>
        // executes DOMReady for the above div
        $('#system_call_info').ready(function() {
        	var progress_id = null;
        	// options for the ajax call
        	// see documentation for all options, possible values of dataType etc
        	opts = {
        		url: '/xhr.php',
        		dataType: 'TEXT',
        		data: {
        			var1: 1,
        			var2: 'b'
        		},
        		// event handler for successful XHR call
        		success: function(response) {
        			if (progress_id) {
        				window.clearInterval(progress_id);
        			}
        			$('#system_call_info').html(response);
        		}
        	};
        	// Execute request to server
        	$.ajax(opts);
        
        // My "progress bar". Replace with whatever representation you want
        var progress = 0;
        progress_id = window.setInterval(function() {
        	++progress;
        	$('#system_call_info').html('Progress: ' + progress + ' / 10');
        	if (progress == 10) {
        		window.clearInterval(progress_id);
        	}
        }, 1000);
        });
        </script>
        

        Where xhr.php does nothing but sleeps for 10 seconds, then echo "Done".

          Thanks, that looks good..

          I'll have a go and see what I can come up with.

            2 months later

            I've only just manage to get back to this.

            Thanks for the sample code, but I've no idea what to do with it :o

            What I'm trying to do is quite simple.

            echo "doing a...."
            Start progress bar
            then exec("commandA")

            stop progress bar
            echo "doing b...."
            Start progress bar
            then exec("commandA")

            stop progress bar
            echo "doing c...."
            Start progress bar
            then exec("commandC")

            etc

            any idea who I can do that ??

              Thanks that does look interesting and one to look out for.

              Is there anyway of doing this that cross browser compatible ?

              All I'm trying to do it print to screen "Doing A".
              Show animated logo/gif etc, whilst that is being displayed run shell exec command.
              When the command completes, stop the logo/gif and repeat..

              Doing B
              Logo/gif
              command B

              etc

                johanafm;11012403 wrote:

                assuming you use jQuery

                jQuery gives you a consistent way of handling things in javascript indepently from the browser implementation, as well as provide some additional useful stuff. So instead of writing code segments separately for IE6, FF, Safari, Chrome... you write it for jQuery which takes care of the rest for you.

                Google jquery and download its latest javascript file to your server, then add this in the head section of your html code

                <script src="path/to/your_jquery_file.js"></sript>
                

                This is what I use for output from my XHR (xml http request), commonly referred to as ajax (asynchronous javascript and xml). Nowdays JSON-encoded data is far more common that XML data though (citation needed). I simply identify the div in the javascript code by the div's id attribute value.

                <div id="system_call_info">
                </div>
                

                The javascript code I provided could go directly in the head part of the html document, but you really should put your javascript code in one or more separate javascript files and include them in the document the same way you did with the jQuery file

                <script src="/path/to/your_js_file.js"></script>
                

                And once you place the js code in a separate file like that you should change the first line to

                <script>$('#system_call_info').ready(foo())</script>
                

                which still resides in the html code following the <div id="..."></div>
                and the first line of the js file should instead be

                function foo() {
                

                with the rest as before.

                Then all you need to do is create a php file called xhr.php and place it in your document root (or change the url property from '/xhr.php' to something else, like '/path/to/whateverfile.php'). This is the file that will execute code on the server, for whatever purpose you see fit. For your trial run, you could just have it check if $POST['var1'] and $POST['var2'] are set and error_log them. They should contain values 1 and b respectively. But also add a sleep(5) to your php file, to make it wait 5 seconds. As a last line in the script, put echo "Done!";

                The request to that file is made with the js code $.ajax(opts). But since the call is made asynchronously, the browser will not hang around waiting for that call to complete. Instead, WHEN it completes, the success handler is executed, but it doesn't really matter when that happens. Thus, the browser immediately continues execution and sets up a function which runs periodically (google "mozilla window.setinterval" for more info) once every 1000 milliseconds = once per second. Every second it will use the "system_call_info" div to display "Progress 1/10", "Progress 2/10" and so on.

                Then, once xhr.php has finished execution, the success handler function is executed. That function runs clearinterval on our periodically executed function, which means that it stops running. In my particular example, this means that the user would see "Progress 5/10" as the last "progress bar" updated, and then it would show whatever output xhr.php produced (using print, echo etc), in this case "Done!".

                As such, this progress bar is pretty naive in its imlementation. If you know in advance that the execution time is always roughly the same, this will work fine. Otherwise you would have to implement some way of tracking progress (such as making several consecutive requests to the server to see how far its come and update the progess bar accordingly).

                  Write a Reply...