ご存知のとおり、PHP にはマルチスレッドなどはありませんが、非同期も実現できますが、これはいくつかの妥協的な方法を使用して行われます。
ここ数日間で私が見つけた PHP 非同期呼び出しの要件と解決策をまとめます。
もちろん、私は疑似コードファーマーであり、私が使用するメソッドはすべて非常に洗練されておらず愚かなメソッドなので、要約、修正、改善する必要があります。
AJAX を使用して実装し、ajax を通じてサーバーに継続的にアクセスし、setInterval を通じて間隔を設定し、backend.php ファイルにアクセスし、収集された数量を取得して、ページの対応する DOM コンテンツを更新します。
私は jQuery をあまりよく学習していないので、コードは次のとおりです:
<span style="color: #008080;"> 1</span> jQuery(document).ready(<span style="color: #0000ff;">function</span><span style="color: #000000;">($) { </span><span style="color: #008080;"> 2</span> <span style="color: #008080;"> 3</span> $('#submit').click(<span style="color: #0000ff;">function</span><span style="color: #000000;">(){ </span><span style="color: #008080;"> 4</span> setInterval("updateMsg()", 1000<span style="color: #000000;">); </span><span style="color: #008080;"> 5</span> $.post('total.php', $('#form1').serialize(), <span style="color: #0000ff;">function</span><span style="color: #000000;">(data, textStatus){ </span><span style="color: #008080;"> 6</span> <span style="color: #0000ff;">var</span> new_data = "<p>本次所要采集的专利总数为:" + data + "</p>"<span style="color: #000000;">; </span><span style="color: #008080;"> 7</span> $('#total_area'<span style="color: #000000;">).html(new_data); </span><span style="color: #008080;"> 8</span> $('#monitor_area').html('<p>正在初始化信息监控.....</p>'<span style="color: #000000;">); </span><span style="color: #008080;"> 9</span> <span style="color: #000000;"> }); </span><span style="color: #008080;">10</span> $.post('test.php',$('#form1'<span style="color: #000000;">).serialize()); </span><span style="color: #008080;">11</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">; </span><span style="color: #008080;">12</span> <span style="color: #000000;"> }); </span><span style="color: #008080;">13</span> <span style="color: #008080;">14</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> updateMsg(){ </span><span style="color: #008080;">15</span> $.get("backend.php",{},<span style="color: #0000ff;">function</span><span style="color: #000000;">(data, textStatus){ </span><span style="color: #008080;">16</span> <span style="color: #0000ff;">var</span> now_total = "<p>目前已采集数量:" + data + "</p>"<span style="color: #000000;">; </span><span style="color: #008080;">17</span> $("#monitor_area"<span style="color: #000000;">).html(now_total); </span><span style="color: #008080;">18</span> <span style="color: #000000;"> }); </span><span style="color: #008080;">19</span> }
申請者の情報を知り、できるだけ早く連絡したい登録システム。登録情報は 10 日以上に 1 件しかない場合があります。
携帯電話のリマインダーは、139にメールを送信する方法を採用しています。
しかし、問題があります。つまり、ユーザーが個人情報を送信するプログラム部分に電子メールを送信するためのコードを記述すると、送信プロセスが非常に遅くなり、場合によっては 3 秒以上かかる場合があり、これは耐えられません。
メールの送信などに時間がかかる場合は「キュー」方式を使用します。もちろん、このキューは RabbitMQ や ZeroMQ ほど高度ではありません。実際には情報がデータベースに保存され、キューに入れられたものとしてカウントされ、データベース内の情報を処理するために cron が設定されます。 、これも愚かな方法です。
1. もちろん、データベースを使用してシミュレーションしましたが、これは同時実行性を考慮して設計されていないため、必然的に失敗します。この時点で、伝説的な RabbitMQ を使用すると、パフォーマンスが大幅に向上するはずです。 Redis データベースもあります。私はこれを使用しましたが、そのリストをメッセージ キューとして使用するのは非常に良いと思います。
2. CURL メソッド、curl_multi は良いことだと言われていますが、CUROPT_TIMEOUT の最小値が 1 であるため、クライアントは少なくとも 1 秒待つ必要があり、これも欠点です。
3.popen() 関数は、指定されたコマンド command の実行によって生成されるプロセスを指すパイプを開きます。
<span style="color: #008080;">pclose</span>(<span style="color: #008080;">popen</span>("/home/xinchen/backend.php &", 'r'));
4.fsockopen() メソッド。このメソッドでは http ヘッダーを自分で結合する必要があります。
5. PHPのマルチプロセス 実はこの方法は、処理する大きなデータをforループに従って細かく分割してvimで処理するというものです。 CLI モードで実行します
php –f example1.php &<span style="color: #000000;"> php –f example2.php </span>&
この愚かな方法を使用して、PHP プロセスをバックグラウンドで実行します...
後で、*uinx の PHP が C と同様のプロセスを直接 pcntl フォークできることを知り、データを収集するときにこの方法を使用すると、CURL や fsockopen と組み合わせると非常に高速になります。 。残念です、しばらく楽しんでいたのに IP がブロックされてしまったのは残念です...
この処理はやはり非常に便利です。
<span style="color: #008080;"> 1</span> <span style="color: #0000ff;">for</span>(<span style="color: #800080;">$i</span> = 0; <span style="color: #800080;">$i</span> $intNum; <span style="color: #800080;">$i</span>++<span style="color: #000000;">) { </span><span style="color: #008080;"> 2</span> <span style="color: #800080;">$pids</span>[<span style="color: #800080;">$i</span>] = pcntl_fork();<span style="color: #008000;">//</span><span style="color: #008000;"> 产生子进程,而且从当前行之下开试运行代码,而且不继承父进程的数据信息</span> <span style="color: #008080;"> 3</span> <span style="color: #0000ff;">if</span>(<span style="color: #800080;">$pids</span>[<span style="color: #800080;">$i</span>] == -1<span style="color: #000000;">) { </span><span style="color: #008080;"> 4</span> <span style="color: #0000ff;">echo</span> "couldn't fork". "\n"<span style="color: #000000;">; </span><span style="color: #008080;"> 5</span> } <span style="color: #0000ff;">elseif</span>(!<span style="color: #800080;">$pids</span>[<span style="color: #800080;">$i</span><span style="color: #000000;">]) { </span><span style="color: #008080;"> 6</span> <span style="color: #008080;">sleep</span>(1<span style="color: #000000;">); </span><span style="color: #008080;"> 7</span> <span style="color: #0000ff;">echo</span> "\n"."第".<span style="color: #800080;">$i</span>."个进程 -> " . <span style="color: #008080;">time</span>(). "\n"<span style="color: #000000;">; </span><span style="color: #008080;"> 8</span> <span style="color: #008000;">//</span><span style="color: #008000;">这里就可以放信息采集抓取等东西的代码了。</span> <span style="color: #008080;"> 9</span> <span style="color: #0000ff;">exit</span>(0);<span style="color: #008000;">//</span><span style="color: #008000;">子进程要exit否则会进行递归多进程,父进程不要exit否则终止多进程</span> <span style="color: #008080;">10</span> <span style="color: #000000;"> } </span><span style="color: #008080;">11</span> }
6. Gearman 分散コンピューティング。さまざまなマシンへのジョブの実行をサポートするために多くのワーカーをオープンします。これは私にはアクセスできないもので、伝説的です。
参考資料:
1. もちろん、これは Brother Bird のブログ「Corner of the Wind and Snow」です。私はこれらの非同期メソッドをすべて彼のブログから見ました。
2. Zhang Yan のブログ、マルチプロセス コンテンツ。