I need to provide interaction between js on html-page and php-script.
- Use AJAX.
Ok. But the problem is that php-script executing for a long time, and i need to know the state of this script processing (e.g. 60% complete)
What should i do? Create 2 php-scripts (client&server) and do ajax-request to client.php which will do requests to server.php via sockets or smth?
Are there more elegant solutions?

- 61
- 5
-
Well, using file can help but it still not my dream. What if it i need to get information from php-script very often. Would not that be too expensive for file system? – Dmitriy Sep 21 '12 at 19:23
-
Reading a file is ridiculously easy for computers. – thatidiotguy Sep 21 '12 at 19:28
6 Answers
What if you had the script doing the processing write its status to a file once in awhile. Make a second script that will read the file and return the status of the original one.

- 8,701
- 13
- 60
- 105
- Ajax call php script and return information that script is runing.
- Main script create lock.file.
- Script called from cron is checking if lock.file exists and run the correct script.
- The correct script saves the current progress into progress.txt.
- Ajax is reading progress.txt and when progress is 100% then return information that script processing is finished.
edited: Thanks to Justin for poiting the timeout problem ;)

- 1,329
- 9
- 20
-
Even if you `fork()` within the main script to do processing in the background, your HTTP server can still abort the request if it's long-running. There are ways around this, but the better solution is to move the time-consuming process completely outside of the web server's realm of responsibility. – Justin ᚅᚔᚈᚄᚒᚔ Sep 21 '12 at 19:34
-
Sure thing, but main script instead of processing operation can only create a lock file and then another script runned from cron when lock file exists can run main process. Scripts called from cli usualy dont have any timeout :) – Norbert Orzechowicz Sep 21 '12 at 19:40
-
You should probably update the answer to include that. The way it's currently worded (*"Main script write progress into progress.txt file"*) doesn't make it clear that the "main script" is being executed by cron and looking for a signal to begin processing. – Justin ᚅᚔᚈᚄᚒᚔ Sep 21 '12 at 19:45
-
How can one measure the progress state in this method ? (like how much percent is being processed by server etc) – palerdot Sep 22 '12 at 07:12
You should never have a long-running process being executed entirely within an HTTP session.
A simple and common approach to this problem is message queuing. Basically, you have your UI queue up the request into a database table and then have external daemon(s) process the queue.
To provide feedback, have the daemon periodically update the table with the status for the row it's currently working on. Then, your javascript code can make AJAX requests to a script that retrieves the status for that work item from the database and displays it to the user.

- 1
- 1

- 15,081
- 7
- 52
- 64
If you want to be really fancy, write output from the php script to stdout, and capture it via a pipe. This would require running the php script using exec() or proc_open() (http://php.net/manual/en/function.proc-open.php) and pipe the output to a file (or if you want to be extra-extra fancy, use node.JS to listen for that data)
There are quite a few ways to accomplish this:
- Node.JS
- An Ajax query every x seconds
- A META/Javascript page reload
- An iframe that is routinely reloading with the status in it.
Good luck!

- 6,690
- 3
- 36
- 64
You could use PHP's output buffering (see ob_flush) to flush the contents at certain points in your script and tailor your JavaScript so that it uses the flushed contents. I believe readyState in your AJAX call won't be set to 4 on flushes so that's where you'll have to handle that yourself (see this article). I think its a much nicer way than writing to a file and checking the contents of that.
on your process.php
:
// 1st task
$_SESSION['progress'] = 0;
// your code for the first task here ...
// 2nd task
$_SESSION['progress'] = 10;
// you code for 2nd task ...
// 3rd task
$_SESSION['progress'] = 17;
// continue ...
// everything finished?
$_SESSION['progress'] = 100;
on your progress.php
:
// simply output
echo $_SESSION['progress'];
now from your client-side, just make a request to your progress.php
, receive the number and give it to your progress bar ...
didn't check that by myself, but hope that it works! :)

- 9,247
- 9
- 53
- 74