phpタイミング計画タスクとfsockopen持続プロセス例


WebサーバーはPHPスクリプトを実行していますが、実行結果に戻るまでに時間がかかります。後のスクリプトは長い間待つ必要があります。実行結果を待たずに簡単にトリガするシナリオだけを実現するには、fscokopen関数で実行できます。
PHPはsocketプログラミングをサポートしています。fscokopen関数はリモートホストに接続されたハンドルを返します。fopenを使って返すハンドルのようにfwrite、fgets、freadなどの操作ができます。fsockopenを使ってローカルサーバに接続し、スクリプトの実行をトリガし、すぐに戻って、スクリプトの実行が完了するまで待つことなく、非同期でPHPを実行する効果を実現します。
例:

<? 
function triggerRequest($url, $post_data = array(), $cookie = array()){ 
  $method = "GET";  // POST GET  
  $url_array = parse_url($url); // URL  
  $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
"; 
  $header .= "Host: ". $url_array['host'] . "\r
"; //HTTP 1.1 Host  
  /*
  $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
";
  $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
";
  $header .= "Accept-Language: en-us,en;q=0.5 ";
  $header .= "Accept-Encoding: gzip,deflate\r
";
   */ 

  $header .= "Connection:Close\r
"; 
  if(!empty($cookie)){ 
    $_cookie = strval(NULL); 
    foreach($cookie as $k => $v){ 
$_cookie .= $k."=".$v."; "; 
    } 
    $cookie_str =  "Cookie: " . base64_encode($_cookie) ." \r
"; // 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
";  
    $post_str .= "Content-Length: ". strlen($_post) ." \r
"; //POST  
    $post_str .= $_post."\r
\r
"; // POST  
    $header .= $post_str; 
  } 
  fwrite($fp, $header); 
  //echo fread($fp, 1024); //  
  fclose($fp); 
  return true; 
}  
これによりfsockopen関数でPHPスクリプトの実行をトリガし、関数が戻ります。次に次の操作を行いました。現在問題があります。クライアントが接続を切断した後、すなわちtrigger Requestが要求を送信した後、すぐに接続を切断した場合、サーバー側で実行中のスクリプトが終了する可能性があります。
PHP内部では、システムが接続状態を維持しています。その状態は三つの可能性があります。
*0 C NORMAL(正常)*1 C ABORTED(異常終了)*2 C TIMEOUT(タイムアウト)PHPスクリプトが正常にNORMAL状態で動作している場合、接続は有効です。クライアントが接続を中断すると、ABORTED状態のフラグが開きます。リモートクライアント接続の中断は、一般的にユーザーがSTOPボタンをクリックすることによって引き起こされる。接続時間がPHPを超える場合(set_を参照。time_limit()関数の場合、TIMEOUT状態のフラグが開きます。
スクリプトは、クライアントが接続を中断したときに終了する必要があるかどうかを決定することができます。シナリオをフルに実行させると、リモートブラウザがなくてもスクリプトの出力を受けることができます。デフォルトでは、リモートクライアントの接続が中断されるとスクリプトが終了します。この処理過程はphp.iniのignore_によってもよい。アメリカ.abortまたはApphe.conf設定で対応する「php_」value ignore_アメリカ.abort「およびignore_アメリカ.abort()関数は制御します。PHPがユーザーの中断を無視していたら、スクリプトは中断されます。shutdown_Function()は、シャットダウンを実行すると呼び出される別の関数を設定します。つまり、シナリオの実行が完了していたり、突然死んでしまったりすると、PHPの実行が終了します。この関数は呼び出しられます。リモートユーザーがSTOPをクリックしてボタンを押した後、スクリプトが再度データを出力しようとすると、PHPは接続が中断されていることを検出します。を選択して、トリガ機能をオフにします。
スクリプトは内蔵されているスクリプトタイマーで中断することもあります。デフォルトのタイムアウト制限は30秒です。この値はphp.iniのmax_を設定できます。execution_timeまたはApache.conf設定で対応する「php_」value max_execution_time"パラメータまたはset_time_limit関数を変更します。カウンタがタイムアウトした場合、スクリプトは上記の接続が中断された場合と同様に終了します。以前登録されたクローズトリガ関数もこの時に実行されます。この閉トリガ関数では、connection_を呼び出しても良い。status()関数は、タイムアウトによってトリガ関数が起動されるかどうかを確認します。タイムアウトがトリガ関数のコールをオフにすると、関数は2を返します。
ABORTEDとTIMEOUTの状態は同時に有効です。これはPHPがユーザの終了操作を無視するということを教えた時に可能です。PHPは、ユーザが接続を中断しましたが、スクリプトがまだ動作している状況に注意します。実行の時間制限があると、スクリプトは終了し、設定されたオフトリガ関数も実行されます。この時、関数connection_を発見します。status()は3を返します。
まだトリガしたいスクリプトに指定されています。

<?php 
  ignore_user_abort(TRUE); // , abort 
  set_time_limit(0); //  
:
<?php 
  register_shutdown_function(callback fuction[, parameters]); //