PHP 非同期通信(curl_multi)

2013/04/04

PHPで、非同期の処理を行いたい。curl_multi()ってのがあるらしい。
ただし、php5からっぽい。

ひとつのみ

$ch = curl_init("http://magazine.music.yahoo.co.jp/rss/ALL/rss.xml"); // Curl Handleを用意
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$rss = curl_exec($ch); // 通信実行し、結果のXMLを取得
curl_close($ch);

複数あり

// 並列通信用マルチハンドルを用意
$mh = curl_multi_init();

// 通信先ごとにCurl Handleを作り、それを $mh にaddしていく
$ch_news = curl_init("http://dailynews.yahoo.co.jp/fc/entertainment/rss.xml");
curl_setopt($ch_news, CURLOPT_RETURNTRANSFER, TRUE);
curl_multi_add_handle($mh, $ch_news);

// 同様に
$ch_music = curl_init("http://magazine.music.yahoo.co.jp/rss/ALL/rss.xml");
curl_setopt($ch_music, CURLOPT_RETURNTRANSFER, TRUE);
curl_multi_add_handle($mh, $ch_music);

// 同様に
$ch_trend = curl_init("http://searchranking.yahoo.co.jp/rss/trend-rss.xml");
curl_setopt($ch_trend, CURLOPT_RETURNTRANSFER, TRUE);
curl_multi_add_handle($mh, $ch_trend);

// せーので複数の通信を同時実行。whileで全て返ってくるのを待ちます
do { curl_multi_exec($mh, $running); } while ( $running );

// 個々のXMLは、それぞれのCurl Handleを指定することで取得できる
$rss_news = curl_multi_getcontent($ch_news);
$rss_music = curl_multi_getcontent($ch_music);
$rss_trend = curl_multi_getcontent($ch_trend);

// 後始末
curl_multi_remove_handle($mh, $ch_news);
curl_close($ch_news);

curl_multi_remove_handle($mh, $ch_music);
curl_close($ch_music);

curl_multi_remove_handle($mh, $ch_trend);
curl_close($ch_trend);

curl_multi_close($mh);

複数あり(2)

/**
* 複数URLのコンテンツ、及び通信ステータスを一括取得する。
* サンプル:
* $urls = array( "http://〜", "http://〜", "http://〜" );
* $results = getMultiContents($urls);
* print_r($results);
*/
function getMultiContents( $url_list ) {
  // マルチハンドルの用意
  $mh = curl_multi_init();

  // URLをキーとして、複数のCurlハンドルを入れて保持する配列
  $ch_list = array();

  // Curlハンドルの用意と、マルチハンドルへの登録
  foreach( $url_list as $url ) {
    $ch_list[$url] = curl_init($url);
    curl_setopt($ch_list[$url], CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch_list[$url], CURLOPT_TIMEOUT, 1); // タイムアウト秒数を指定
    curl_multi_add_handle($mh, $ch_list[$url]);
  }

  // 一括で通信実行、全て終わるのを待つ
  $running = null;
  do { curl_multi_exec($mh, $running); } while ( $running );

  // 実行結果の取得
  foreach( $url_list as $url ) {
    // ステータスとコンテンツ内容の取得
    $results[$url] = curl_getinfo($ch_list[$url]);
    $results[$url]["content"] = curl_multi_getcontent($ch_list[$url]);

    // Curlハンドルの後始末
    curl_multi_remove_handle($mh, $ch_list[$url]);
    curl_close($ch_list[$url]);
  }

  // マルチハンドルの後始末
  curl_multi_close($mh);

  // 結果返却
  return $results;
}

http://techblog.yahoo.co.jp/architecture/api1_curl_multi/

新着(ニュース関連以外)

2017-07-19
折れ線グラフをもう少しゆるやかに・・・というか何というか・・・調べていくと「移動平均」っていう言葉にたどり着いた
2017-07-10
FuelPHPの1.8をダウンロードして使っていたらセッションが使えないということに気付いた。
2017-06-27
MACにWin10をインストールしてみた:再挑戦。
2017-06-25
「簡単」っていうヤツらが多いけど・・・難しいぞ。
2017-06-06
FuelPHPのOILでtry・catchを使ったらエラーになった。