1

PHP で SEO 関連のスクリプトに取り組んでおり、クロール プロセスが終了したら、さまざまなモジュール (それぞれが .php ファイルです) を同時に実行する必要があります。つまり、10 個を超える .php ファイルを並行して実行する必要があります。

アプリケーションはシーケンスで動作していたため、1 つのスクリプトが終了すると、ユーザーのブラウザは次のスクリプトに転送されました。スクリプトのそれぞれがデータベースへの接続を確立し、クロールされた Web アプリケーションにさまざまな HTTP パケットを送信しています。

popen を使用してこれにアプローチできることを理解していますか? このモジュールのそれぞれから、それらをトリガーするメイン スクリプトに情報を受け取る方法はありますか? これがどのように機能するかを確認するために、誰かが非常に短いスニペットを提供できますか?

4

2 に答える 2

1

PHP で複数の並列ジョブを実行するには、この手法を試してください。この例では、実行したい j1.php と j2.php の 2 つのジョブ ファイルがあります。サンプル ジョブは、派手なことは何もしません。ファイル j1.php は次のようになります。

$jobname = 'j1';
set_time_limit(0);
$secs = 60;

while ($secs) {
        echo $jobname,'::',$secs,"\n";
        flush(); @ob_flush();  ## make sure that all output is sent in real-time
        $secs -= 1;
        $t = time();
        sleep(1); // pause
}

flush(); する理由 @ob_flush(); エコーまたは出力するとき、文字列が PHP によってバッファリングされ、後で送信されることがあります。これら 2 つの機能により、すべてのデータがすぐに送信されます。

次に、ジョブ j1 と j2 の調整を行う 3 番目のファイル、control.php があります。このスクリプトは、JobStartAsync() で fsockopen を使用して j1.php と j2.php を非同期的に呼び出すため、j1.php と j2.php を並行して実行できます。j1.php および j2.php からの出力は、JobPollAsync() を使用して control.php に返されます。

#
# control.php
#
function JobStartAsync($server, $url, $port=80,$conn_timeout=30, $rw_timeout=86400)
{
    $errno = '';
    $errstr = '';

    set_time_limit(0);

    $fp = fsockopen($server, $port, $errno, $errstr, $conn_timeout);
    if (!$fp) {
       echo "$errstr ($errno)<br />\n";
       return false;
    }
    $out = "GET $url HTTP/1.1\r\n";
    $out .= "Host: $server\r\n";
    $out .= "Connection: Close\r\n\r\n";

    stream_set_blocking($fp, false);
    stream_set_timeout($fp, $rw_timeout);
    fwrite($fp, $out);

    return $fp;
}

// returns false if HTTP disconnect (EOF), or a string (could be empty string) if still connected
function JobPollAsync(&$fp) 
{
    if ($fp === false) return false;

    if (feof($fp)) {
        fclose($fp);
        $fp = false;
        return false;
    }

    return fread($fp, 10000);
}

###########################################################################################


if (1) {  /* SAMPLE USAGE BELOW */

    $fp1 = JobStartAsync('localhost','/jobs/j1.php');
    $fp2 = JobStartAsync('localhost','/jobs/j2.php');


    while (true) {
        sleep(1);

        $r1 = JobPollAsync($fp1);
        $r2 = JobPollAsync($fp2);

        if ($r1 === false && $r2 === false) break;

        echo "<b>r1 = </b>$r1<br>";
        echo "<b>r2 = </b>$r2<hr>";
        flush(); @ob_flush();
    }

    echo "<h3>Jobs Complete</h3>";
}

よく読んだ

PHP での分割統治と並列処理

ソースから

于 2012-10-25T13:45:46.423 に答える
1

PHPのさまざまなファイルに依存関係がない場合は、次のように実装できるマルチカールアプローチを使用できると思います:-

    $linkArray = array('file1.php', 'file2.php','file3.php','file4.php','file5.php');
    $nodes = ($linkArray);
    $node_count = count($nodes);

    $curl_arr = array();
    $master = curl_multi_init();
    $counter = 0;
    for($i = 0; $i < $node_count; $i++)
    {
      $url =$nodes[$i];
      $curl_arr[$i] = curl_init($url);
      curl_setopt($curl_arr[$i], CURLOPT_RETURNTRANSFER, true);
      curl_multi_add_handle($master, $curl_arr[$i]);
    }

do {
    curl_multi_exec($master,$running);
} while($running > 0);

for($k=0;$k<$node_count;$k++){

  $result = curl_multi_getcontent  ($curl_arr[$k]); // contains the output of individual files

}
于 2012-10-25T13:55:41.827 に答える