How to stop PHP from sending data to the client while PHP code is still running on the server?

This question came up to me when I came across an error that made my PHP program run endlessly. Here is an example of a situation:

Suppose I have a PHP webpage that receives an image upload (the page is probably the response page for the image upload form). On the server, the script must store the image in a temporary file. The script then issues a confirmation message to the client, and then stops sending data so that the client does not wait. Then the script should continue execution, process the image (for example, resize it) until the end.

I think this โ€œtechniqueโ€ may be useful, so the client will not wait during labor-intensive processes, therefore it prevents timeouts.

Also, can this be solved using HTTP methods?

+4
source share
5 answers

Yes.

This can easily be done without asynchronous processing if you use the HTTP headers correctly.

Under normal circumstances, PHP will stop processing as soon as the client at the other end closes the connection. If you want to continue processing after this event, you need to do one thing: tell PHP to ignore user interrupts. How?

ignore_user_abort()

This will allow your script device to continue to work even after the client receives the dash line. But we also face the problem of how to inform the client that the request he completed has been completed in order to close the connection. Typically, PHP transparently handles sending these headers for us, unless we specify them. Here, however, we need to do this explicitly or the client will not know when we want them to stop reading the answer.

To do this, we must send the appropriate HTTP headers to tell the client when to close:

 Connection: close Content-Length: 42 

This combination of headers tells the client that after it reads 42 bytes of the body response, the message is complete and that they should close the connection. There are several consequences to this method:

  • You have to generate your answer BEFORE sending any output, because you need to determine its size of the length of the content in bytes so that you can send the correct header.
  • You must send these headers before you echo the call.

So your script might look something like this:

 <?php ignore_user_abort(); // do work to determine the response you want to send ($responseBody) $contentLength = strlen($responseBody); header('Connection: close'); header("Content-Length: $contentLength"); flush(); echo $responseBody; // --- client will now disconnect and you can continue processing here --- 

The big "gotchya" with this method is that when you run PHP in web-based SAPI, you can easily overcome the maximum time directive if you are involved in labor-intensive processing after the end-user client closes the connection. If this is a problem, you may need to consider asynchronous processing using cron, because there is no time limit when PHP runs in the CLI environment. Alternatively, you can simply limit the time of your scripts in a web environment using set_time_limit docs .

It is worth noting that if you do something like this, you can also add a check to connection_aborted() docs when generating your response organ, so that you can avoid additional processing if the user interrupted before the transfer was completed.

+10
source

I have a problem with the same problem when I upload an image to twitter and facebook from iphone via php web service.

If the processing time for loading the image is not so long, you can check out @Musa comment, this may help you, but if processing takes too much time, try these steps.

  1. Image store in folder 2. Fetch image from folder using cron 3. Cron run for every 2 min in backend 

this will reduce processing time.

Hope this helps you.

+2
source

It is advisable to do this asynchronously. That is, create another script that only processes previously created tmp files and runs it using cron (not even including apache). When php works as a web server module, it should be designed to quickly form a response, and then leave to free up resources for the next request.

You are doing the right thing in this way; just keep going one small architectural step further and fully open the request from the heavy climb that is about to happen.

+1
source

You can do this in several ways:

1 #

 ob_start(); //output header("Content-Length: ".ob_get_length()); header("Connection: close"); ob_end_flush(); //do other stuff 

2 #

Using system () or exec () PHP, close Process

3 #

Close the process using the Script shell

+1
source

You can use ob_implicit_flush(), turn implicit flushing on and off. Implicit flushing will result in a reset operation after each output call, so explicit calls to flush () are no longer needed.

talk to

How to implement this script using PHP?

OR

You should create a standalone cron that will start after a certain time and execute the asynchronous path, not letting the user know what processing is in progress, or not letting the user wait. Thus, you can even detect malfunctioning cases.

And you should also try to minimize load times.

+1
source

All Articles