How to call PHP without blocking the stream?

I have 2 PHP files. One file is caller.php and the other is worker.php

caller.php will run work.php on the system (linux), and caller.php should be terminated immediately (while work.php is still running on the server)

Work.php takes a lot of time and it will write the status to a database or file.

I want to open caller.php in a browser that launches "php worker.php", close the browser, return after 5 minutes and check the status .. (or the script will send mail after completion) - any ideas how to do this?

+4
source share
3 answers

You can complete the connection with the client and continue processing, everything is done. You can also increase php timeout if processing takes longer than the global php / httpd configuration allows. See set_time_limit(); .

This is not exactly what you requested, but I think it could be an X / Y problem, so here we use a technique that can be used to:

  • Display page Processing started for user.
  • close user connection.
  • start longer processing.

So basically it meets your described needs, not "how to make X?"

Caller

 // Ignore user abort and set Connection close header ignore_user_abort(true); header("Connection: close"); // Start controlled buffering ob_start(); echo "<h1>Processing started, come back tomorrow to see results</h1>"; // Get buffer length and manually add it to headers. $size = ob_get_length(); header("Content-Length: $size"); // Flush buffers, user sees "Processing started" message. ob_end_flush(); flush(); // At this point connection to client should be closed already. // Here we start our worker, there is no need to do fork() or // anything like that. Client browser is not listening anymore. // All we need to do is simply start working and start writing // status logs to somewhere so that client can retrieve status // with another request, let say from checkworkerstatus.php include "worker.php"; $worker = new worker(); $worker->start_long_processing(); 

Not unlock or kill caller to leave worker on?

This is correct, and this is because there is no need.

Yes, you asked for behavior when "caller.php starts work.php on the system (linux) and caller.php should be stopped immediately (while work.php is still running on the server)" I>. However, there is no need to do it this way if you do not want to make a multi-threaded application-single application with php . Just let users 1. start something, 2. leave it running, 3. disconnect users, 4. go back to start, where users can start something else or exit if there is already a pacifier.

Of course, you can replace everything after flush(); whatever, the difference is that clients no longer listen, so all the output goes into a black hole named / dev / null. For example, check it out like this:

 ...end_flush(); flush(); // At this point connection to client should be closed already. echo "Nobody sees this message"; while(rand(0,10) != 1) { echo "Nobody sees this message"; error_log(date("mdyHis")." Still running..."); sleep(10); } ... 

See http://php.net/features.connection-handling for details.
Also read http://php.net/function.flush if there seems to be a problem with the cleanup buffer and closing the user connection.
There is another question (with answers) about why PHP does not support multithreading?

+2
source
  • Caller does the work
  • The worker creates a FIFO file in / tmp / and writes progress information to it (you can also use sockets)
  • Caller reads this file and shows the actual progress of the user.

If you configure Apache / nginx well, it will allow you to execute two PHP files at the same time (for example, mine).

You should read about posix_mkfifo: http://php.net/manual/en/function.posix-mkfifo.php (there are usage examples).

+1
source

this may be a little powerful, but is the fastest and most direct way:

  • caller creates html with <IFRAME>
  • SRC IFRAME is a worker (here the access parameters of the caller to the worker as GET-params)
  • the first lines of the employee are in the code below

code:

 ignore_user_abort(true); set_time_limit(0); 

when closing the browser desktop (should) countinue work!

see http://www.php.net/manual/en/function.ignore-user-abort.php

+1
source

All Articles