views:

68

answers:

5

Hi everyone,

I am working in a tool in PHP that processes a lot of data and takes a while to finish. I would like to keep the user updated with what is going on and the current task processed.

What is in your opinion the best way to do it? I've got some ideas but can't decide for the most effective one:

  • The old way: execute a small part of the script and display a page to the user with a Meta Redirect or a JavaScript timer to send a request to continue the script (like /script.php?step=2).

  • Sending AJAX requests constantly to read a server file that PHP keeps updating through fwrite().

  • Same as above but PHP updates a field in the database instead of saving a file.

Does any of those sound good? Any ideas?

Thanks!

+2  A: 

I suggest using the AJAX method, but not using a file or a database. You could probably use session values or something like that, that way you don't have to create a connection or open a file to do anything.

Kerry
PHP sessions are stored in files.
Frank Farmer
Not necessarily, buy by default, yes. I still think its quicker than you reader and writing on your own.
Kerry
Nice, didn't know you could do that. This is the simplest yet most effective solution I've read so far, but how do you set up the session storage method? And where are they stored if not in a file, RAM maybe? Cheers Kerry
XaviEsteve
I wouldn't worry about the session storage method and I would leave it writing to files, but you can do so through php.ini or possibly .htaccess. They're usually stored in a tmp directory, something like /var/tmp (varies per server). If you run `phpinfo()` on a page it *should* tell you
Kerry
Indeed, I guess I'll use the file method. Don't want to edit the server too much and also the info is more flexible if stored in a file (to use it as an API for example).
XaviEsteve
+1  A: 

In the past, I've just written messages out to the page and used flush() to flush the output buffer. Very simple, but it may not work correctly on every web server or with every web browser (as they may do their own internal buffering).

Personally, I like your second option the best. Should be reliable and fairly simple to implement.

Eric Petroelje
I will often do this for personal tools I use on my own server locally (if you're the only one who will see it, why bother with AJAX?), but I wouldn't rely on this in a production environment.
Dustin Fineout
+2  A: 

Rather than writing to a static file you fetch with AJAX or to an extra database field, why not have another PHP script that simply returns a completion percentage for the specified task. Your page can then update the progress via a very lightweight AJAX request to said PHP script.

As for implementing this "progress" script, I could offer more advice if I had more insight as to what you mean by "processes a lot of data". If you are writing to a file, your "progress" script could simply check the file size and return the percentage complete. For more complex tasks, you might assign benchmarks to particular processes and return an estimated percentage complete based on which process has completed last or is currently running.

UPDATE

This is one suggested method to "check the progress" of an active script which is simply waiting for a response from a request. I have a data mining application that I use a similar method for.

In your script that makes the request you're waiting for (the script you want to check the progress of), you can store (either in a file or a database, I use a database as I have hundreds of processes running at any time which all need to track their progress, and I have another script that allows me to monitor progress of these processes) a progress variable for the process. When the process begins, set this to 1. You can easily select an arbitrary number of 'checkpoints' the script will pass and calculate the percentage given the current checkpoint. For a large request, however, you might be more interested in knowing the approximate percent the request has completed. One possible solution would be to know the size of the returned content and set your status variable according to the percentage received at any moment. I.e. if you receive the request data in a loop, each iteration you could update the status. Or if you are downloading to a flat file you could poll the size of the file. This could be done less accurately with time (rather than file size) if you know the approximate time the request should take to complete and simply compare against the script's current execution time. Obviously neither of these are perfect solutions, but I hope they'll give you some insight into your options.

Dustin Fineout
Hi Dustin, the tool is a feed crawler so most part of the process is just waiting for the response. How do you have another PHP script "call" an active script to get the percentage? Thank you!
XaviEsteve
I've updated with a brief discussion of how you might go about doing that :)
Dustin Fineout
Thanks for the detailed explanation Dustin!
XaviEsteve
A: 

I like option 2 - using AJAX to read a status file that PHP writes to periodically. This opens up a lot of different presentation options. If you write a JSON object to the file, you can easily parse it and display things like a progress bar, status messages, etc...

thetaiko
A: 

A 'dirty' but quick-and-easy approach is to just echo out the status as the script runs along. So long as you don't have output buffering on, the browser will render the HTML as it receives it from the server (I know WordPress uses this technique for it's auto-upgrade).

But yes, a 'better' approach would be AJAX, though I wouldn't say there's anything wrong with 'breaking it up' use redirects.

Why not incorporate 1 & 2, where AJAX sends a request to script.php?step=1, checks response, writes to the browser, then goes back for more at script.php?step=2 and so on?

TheDeadMedic