Created
April 6, 2012 16:33
-
-
Save hirak/2321179 to your computer and use it in GitHub Desktop.
curl_multiでHTTP非同期リクエストを行うサンプル ref: http://qiita.com/items/1c67b51040246efb4254
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* curl_multiでHTTP複数リクエストを並列実行するテンプレ | |
* | |
*/ | |
//タイムアウト時間を決めておく | |
$TIMEOUT = 10; //10秒 | |
/* | |
* 1) 準備 | |
* - curl_multiハンドラを用意 | |
* - 各リクエストに対応するcurlハンドラを用意 | |
* リクエスト分だけ必要 | |
* * レスポンスが必要な場合はRETURNTRANSFERオプションをtrueにしておくこと。 | |
* - 全てcurl_multiハンドラに追加 | |
*/ | |
$mh = curl_multi_init(); | |
$urls = array( | |
'http://localhost/sleep.php?wait=3', | |
'http://localhost/sleep.php?wait=2', | |
'http://localhost/sleep.php?wait=1', | |
); | |
foreach ($urls as $u) { | |
$ch = curl_init(); | |
curl_setopt_array($ch, array( | |
CURLOPT_URL => $u, | |
CURLOPT_RETURNTRANSFER => true, | |
CURLOPT_TIMEOUT => $TIMEOUT, | |
CURLOPT_CONNECTTIMEOUT => $TIMEOUT, | |
)); | |
curl_multi_add_handle($mh, $ch); | |
} | |
/* | |
* 2) リクエストを開始する | |
* - curl_multiでは即座に制御が戻る(レスポンスが返ってくるのを待たない) | |
* - いきなり失敗するケースを考えてエラー処理を書いておく | |
*/ | |
$stat = curl_multi_exec($mh, $running); //multiリクエストスタート | |
if ( ! $running || $stat !== CURLM_OK) { | |
throw new RuntimeException('リクエストが開始出来なかった'); | |
} | |
/* | |
* 3) レスポンスをcurl_multi_selectで待つ | |
* - 何かイベントがあったらループが進む | |
* selectはイベントが起きるまでCPUをほとんど消費せずsleep状態になる | |
* - どれか一つレスポンスが返ってきたらselectがsleepを中断して何か数字を返す。 | |
* | |
*/ | |
do switch (curl_multi_select($mh, $TIMEOUT)) { //イベントが発生するまでブロック | |
// ->最悪$TIMEOUT秒待ち続ける。タイムアウトは全体で統一しておくと無駄がない | |
case -1: //selectに失敗。通常は起きないはず… | |
case 0: //タイムアウト -> 必要に応じてエラー処理に入るべき | |
continue 2; //ここではcontinueでリトライします。 | |
default: //どれかが成功 or 失敗した | |
$stat = curl_multi_exec($mh, $running); //ステータスを更新 | |
do if ($raised = curl_multi_info_read($mh, $remains)) { | |
//変化のあったcurlハンドラを取得する | |
$info = curl_getinfo($raised['handle']); | |
echo "{$info['url']}: {$info['http_code']}\n"; | |
$response = curl_multi_getcontent($raised['handle']); | |
if ($response === false) { | |
//エラー。404などが返ってきている | |
echo 'ERROR!!!', PHP_EOL; | |
} else { | |
//正常にレスポンス取得 | |
echo $response, PHP_EOL; | |
} | |
curl_multi_remove_handle($mh, $raised['handle']); | |
curl_close($raised['handle']); | |
} while ($remains); | |
//select前に全ての処理が終わっていたりすると | |
//複数の結果が入っていることがあるのでループが必要 | |
} while ($running); | |
echo 'finished', PHP_EOL; | |
curl_multi_close($mh); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
* セキュリティ的に問題のあるスクリプトなので実験以外では使わないでね。 | |
*/ | |
sleep((int)$_GET['wait']); | |
header('Content-Type: text/plain'); | |
echo $_GET['wait']; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment