php Timed Scheduled Tasks and fsockopen Persistent Process Instances

  • 2021-06-28 11:53:29
  • OfStack

The Web server executes an PHP script, sometimes taking a long time to return to the result of execution, and subsequent scripts will need to wait a long time to continue execution.
If you want to simply trigger the execution of a time-consuming script without waiting for the results to execute, you can do the next step directly by using the fscokopen function.

PHP supports socket programming. The fscokopen function returns a handle to a remote host connection, which can be operated on as fwrite, fgets, fread, etc. using handle 1 returned by fopen.
Connect to the local server using fsockopen, trigger the execution of the script, then return immediately without waiting for the completion of the script execution to achieve the effect of asynchronous execution of PHP.

Example:


<?  
function triggerRequest($url, $post_data = array(), $cookie = array()){  
  $method = "GET";  // adopt POST perhaps GET transmit 1 Some parameters give the script to trigger   
  $url_array = parse_url($url); // Obtain URL information   
  $port = isset($url_array['port'])? $url_array['port'] : 80;    
  $fp = fsockopen($url_array['host'], $port, $errno, $errstr, 30);  
  if (!$fp) {  
    return FALSE;  
  }  
  $getPath = $url_array['path'] ."?". $url_array['query'];  
  if(!empty($post_data)){  
    $method = "POST";  
  }  
  $header = $method . " " . $getPath;  
  $header .= " HTTP/1.1\r\n";  
  $header .= "Host: ". $url_array['host'] . "\r\n "; //HTTP 1.1 Host Domain cannot be omitted   
  /* The following header information fields can be omitted  
  $header .= "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13 \r\n"; 
  $header .= "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,q=0.5 \r\n"; 
  $header .= "Accept-Language: en-us,en;q=0.5 "; 
  $header .= "Accept-Encoding: gzip,deflate\r\n"; 
   */  

  $header .= "Connection:Close\r\n";  
  if(!empty($cookie)){  
    $_cookie = strval(NULL);  
    foreach($cookie as $k => $v){  
$_cookie .= $k."=".$v."; ";  
    }  
    $cookie_str =  "Cookie: " . base64_encode($_cookie) ." \r\n"; // transmit Cookie  
    $header .= $cookie_str;  
  }  
  if(!empty($post_data)){  
    $_post = strval(NULL);  
    foreach($post_data as $k => $v){  
$_post .= $k."=".$v."&";  
    }  
    $post_str  = "Content-Type: application/x-www-form-urlencoded\r\n";   
    $post_str .= "Content-Length: ". strlen($_post) ." \r\n"; //POST Length of data   
    $post_str .= $_post."\r\n\r\n "; // transmit POST data   
    $header .= $post_str;  
  }  
  fwrite($fp, $header);  
  //echo fread($fp, 1024); // Server Return   
  fclose($fp);  
  return true;  
}   

This triggers the execution of an PHP script through the fsockopen() function, and the function returns.Next step.
There is a problem: Closing the connection immediately after the client disconnects, that is, after triggerRequest sends the request, may cause the script executing on the server to exit

Inside PHP, the system maintains a connection state, which has three possible scenarios:

* 0 NORMAL (normal)
* 1 ABORTED (abnormal exit)
* 237EN (timeout)

The connection is valid when the PHP script is running properly in the NORMAL state.When the client disconnects, the ABORTED status flag is opened.The disconnection of remote client connections is usually caused by the user clicking the STOP button.When the connection time exceeds PHP (see set_time_When the limit() function is executed, the marker for the TIMEOUT state is opened.

You can decide if the script needs to exit when the client disconnects.Sometimes it is convenient to have the script run completely, even if no remote browser accepts the output of the script.By default, the script exits when the remote client connection is broken.This process can be performed by ignore_of php.iniuser_abort or the corresponding "php_in the Apache.conf setup"value ignore_user_abort "and ignore_user_abort() function to control.If PHP is not told to ignore the user's interrupt, the script will be interrupted unless via register_shutdown_function(), which allows us to set up another function that can be called when execution is closed. That is, when our script execution completes or accidentally dies causing PHP execution to close, our function will be called. When a remote user clicks the STOP button and the script attempts to output data again, PHP will detect that the connection has been broken.And call the close trigger function.

Scripts may also be interrupted by built-in script timers.The default timeout limit is 30 seconds.This value can be set by setting max_for php.iniexecution_The corresponding "php_in the time or Apache.conf settingsvalue max_execution_time "parameter or set_time_limit() function to change.When the counter times out, the script will exit similar to the above disconnected connection, and the previously registered close trigger function will execute.In this close trigger function, you can call connection_The status() function checks if the timeout causes the close trigger function to be called.If the timeout causes a call to close the trigger function, the function returns 2.

Note that the ABORTED and TIMEOUT states can be valid simultaneously.This is possible when telling PHP to ignore the user's exit action.PHP will still be aware that the user has disconnected but the script is still running.If the time limit for running is reached, the script will exit and the set close trigger function will be executed.Function connection_is found at this timestatus() returns 3.

So it's also indicated in the script to trigger:


<?php  
 * ignore_user_abort(TRUE); // If the client disconnects, it will not cause a script abort  
 * set_time_limit(0); // Cancel script execution delay cap   
 Or use : 
<?php  
 * register_shutdown_function(callback fuction[, parameters]); // Functions executed when the registration script exits  


Related articles: