4

コマンドラインアプリケーションを作成しています。ログイン手順を実行した後、cURLを介して複数のPOSTリクエストを同時に送信する必要があります。つまり、送信リクエストはセッションIDなどを送信する必要があります。

イベントのチェーンは次のとおりです。

  1. curl_initでcURL接続を開きます
  2. curl_execを使用してPOSTリクエストを送信するリモートサイトにログインし、応答として返されるHTMLコードを取得します
  3. 同じサイトに同時に複数のPOSTリクエストを送信します。

私はそのようなものを使うことを考えていました:

// Init connection

$ch = curl_init();

// Set curl options

curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_POST, 1);

// Perform login

curl_setopt($ch, CURLOPT_URL, "http://www.mysite/login.php");
$post = array('username' => 'username' , 'password' => 'password');
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$result = curl_exec($ch);

// Send multiple requests after being logged on

curl_setopt($ch, CURLOPT_TIMEOUT_MS, 1);

for($i = 0 ; $i < 10 ; $i++){
    $post = array('myvar' => 'changing_value');
    curl_setopt($ch, CURLOPT_URL, 'www.myweb.ee/changing_url');
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
    curl_exec($ch);
}

しかし、ループ内の最初のリクエストのみが送信されているように見えるため、これは機能していないようです。

おそらく1つの解決策を使用curl_multi_initしますが、それぞれのオプションを変更して同じcURLハンドルを複数回渡すことができるかどうかはわかりません。

これらの同時リクエストに対してサーバーからの応答は必要ありませんが、何らかの方法でそれを実行できれば素晴らしいと思います。

誰かが私を正しい方向に押してくれるなら、それは完璧でしょう。

4

2 に答える 2

6

リクエストごとに新しいカールハンドルを作成してから、http://www.php.net/manual/en/function.curl-multi-add-handle.phpに登録する必要があります。

これが私のコードベースからリッピングして適応させたコードです。そこにエラーチェックを追加する必要があることに注意してください。

function CreateHandle($url , $data) {
    $curlHandle = curl_init($url);

    $defaultOptions = array (
        CURLOPT_COOKIEJAR => 'cookies.txt' ,
        CURLOPT_COOKIEFILE => 'cookies.txt' ,

        CURLOPT_ENCODING => "gzip" ,
        CURLOPT_FOLLOWLOCATION => true ,
        CURLOPT_RETURNTRANSFER => true ,
        CURLOPT_POST => 1,
        CURLOPT_POSTFIELDS => $data
    );

    curl_setopt_array($curlHandle , $defaultOptions);

    return $curlHandle;
}

function MultiRequests($urls , $data) {
    $curlMultiHandle = curl_multi_init();

    $curlHandles = array();
    $responses = array();

    foreach($urls as $id => $url) {
        $curlHandles[$id] = CreateHandle($url , $data[$id]);
        curl_multi_add_handle($curlMultiHandle, $curlHandles[$id]);
    }

    $running = null;
    do {
        curl_multi_exec($curlMultiHandle, $running);
    } while($running > 0);

    foreach($curlHandles as $id => $handle) {
        $responses[$id] = curl_multi_getcontent($handle);
        curl_multi_remove_handle($curlMultiHandle, $handle);
    }
    curl_multi_close($curlMultiHandle);

    return $responses;
}
于 2012-10-11T13:21:18.860 に答える
2

より速く、より効率的なオプションがあります...カールを使用する必要はまったくありません...

http://uk3.php.net/manual/en/book.pthreads.php http://pthreads.org

最新のソース、peclのリリースについてはgithubを参照してください...。

file_get_contentsは魅力的に見えるかもしれませんが、PHPはこのようにスレッド化されて実行されるようには設計されていません。ソケットレイヤーなどは消費を考慮していないため、CPU使用率を節約するために、読み取りの合間に開いてスリープする方がよい場合があります。 ...しかし、それを行うとはるかに良くなります...そしてそれをどのように行うかは、タスクにどのような種類のリソースを割り当てたいかによって異なります...

于 2012-10-11T16:23:45.717 に答える