PHP は、主流の観点からはプロセス指向の言語です。その最大の欠点は、プログラムの実行が最初から最後までロジックに従って実行されることです。これが、主流のプログラミング言語の中で PHP が高水準言語として開発されることを制限する理由の 1 つです。
PHP では、特定の操作を実行するときに、実際に別の操作を実行したい場合があります。ユーザーがチケットを取得しているときに、クエリのためにデータベースに接続するためにユーザーがキューに並ぶことを望まない場合があります。を挿入し、完了後にユーザー結果を返します。実際、ユーザーが送信した後は、チケットを正常に取得したことをユーザーに直接伝えることができ、処理をバックグラウンドに任せることができます。 。もちろん、現在ではメッセージ リストを使用して、ユーザーが送信した各リクエストをメッセージ キューに保存し、ユーザーが喜んでページを閉じた後も、実際には背景がそのままになっています。メッセージを 1 つずつ受信して、キューからリクエストを削除して操作します。この記事では、異種混合メソッドを使用して、ユーザーを待たせることなくバックグラウンドで実行される操作を実現します。
まず、リクエスト エントリを作成する必要があります:
送信されたデータ
バックグラウンドに送信
それが完了したことをユーザーに伝えます
次に、バックグラウンド ハンドラーが必要ですユーザーがオンラインかどうかを確認します。操作には影響しません:
<?php ignore_user_abort(true); set_time_limit(0);
受信データ
データ処理
さて、問題は、コードの最初の部分で、どのように「バックグラウンドに送信」するかということです。この関数は、ノンブロッキング リクエストを通じて実装されます。つまり、アクセス可能な URL を作成し、この URL で 2 番目のプログラムを実行し、リクエストを通じて URL を要求することで、2 番目のプログラムの自動実行をアクティブにします。
次にコードを直接見てみましょう:
// 远程请求(不获取内容)函数 function _sock($url) { $host = parse_url($url,PHP_URL_HOST); $port = parse_url($url,PHP_URL_PORT); $port = $port ? $port : 80; $scheme = parse_url($url,PHP_URL_SCHEME); $path = parse_url($url,PHP_URL_PATH); $query = parse_url($url,PHP_URL_QUERY); if($query) $path .= '?'.$query; if($scheme == 'https') { $host = 'ssl://'.$host; } $fp = fsockopen($host,$port,$error_code,$error_msg,1); if(!$fp) { return array('error_code' => $error_code,'error_msg' => $error_msg); } else { stream_set_blocking($fp,true);//开启了手册上说的非阻塞模式 stream_set_timeout($fp,1);//设置超时 $header = "GET $path HTTP/1.1\r\n"; $header.="Host: $host\r\n"; $header.="Connection: close\r\n\r\n";//长连接关闭 fwrite($fp, $header); usleep(1000); // 这一句也是关键,如果没有这延时,可能在nginx服务器上就无法执行成功 fclose($fp); return array('error_code' => 0); } }
この関数は fsockopen を使用して URL にアクセスしますが、アクセスする際に URL に表示されているコンテンツを取得する必要はありません。アクセス要求を送信します。要求が到着したらすぐにこのアクセスを閉じます。この利点は、訪問した URL から信頼できる情報が返されるまで待つ必要がないため、時間が節約されることです。このコードの実行時間は 0.1 ~ 0.2 秒であり、通常の訪問者にはほとんど知覚されません。したがって、使用するときは、この関数と対応する URL を呼び出すだけで済みます。ただし、ここではデータ送信部分は提供されていません。実際には、$header に投稿コンテンツを追加するだけです。
fsockopen に加えて、curl も実際にはこの効果を実現できます。一部のホストは fsockopen をサポートしていないため、curl を使用してそれを実現できます。
function _curl($url) { $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($ch,CURLOPT_TIMEOUT,1); $result = curl_exec($ch); curl_close($ch); return $result; }
このコードの重要な点は、タイムアウトを 1 秒だけ提供することです。これは、返されたコンテンツが受信されたかどうかに関係なく、curl がリクエストを行うことを意味し、アクセスは 1 秒後に閉じられるため、この関数のデータは 1.0 ~ 1.1 秒の間です。しかし、ユーザーにとって、データ処理が必要なアプリケーションの場合、1 秒の待ち時間はほとんど無視されます。よりシンプルでわかりやすいコードを使用したい場合は、curl を選択して実装することができます。