php5.6.24 環境でWEB APIへ複数のデータを一括でPOSTし、更新する処理を作成中です。
参考にしているコードはcurl_multiでHTTP並行リクエストを行うサンプル
curl_multi_select時に一部データがfalseしか取得できない現象が発生し困り果てています。
同一のデータで複数回実行した際にも、一部データのみFALSEになる場合や、全件正常に取得できる場合などもあります。
curl_multi_info_read実行時に複数のデータを掴んでいることもあるとの記事を見つけたのですが、複数のデータを取得する繰り返し処理を下記コードに追加する必要があるでしょうか。
今回、作成している処理では、同一のAPIへCURLOPT_POSTFIELDSに持たせたキー値を元にした更新処理となります。
上記の参考記事以外にもあちこち見ているのですが、基本的に別々のAPI(URL)への接続を想定しており、
同一API(URL)への並列処理を想定したものが見当たりません。
また、根本的に同一のURLへの並列アクセスの場合は、レスポンスが正常に取得できないことなどはあるでしょうか。
よろしくお願いいたします。
php
1<?php 2//タイムアウト時間を決めておく 3$TIMEOUT = 10; //10秒 4 5$mh = curl_multi_init(); 6$url = 'http://example.com/api' 7$header = array("Authorization:Bearer " . $accessToken,); 8 9$i = 0; 10 11foreach($datas as $data) { 12 $params = array( 13 'id' => $data->id, 14 ... 15 ... 16 ... 17 ); 18 19 ${$i} = curl_init($url); 20 curl_setopt_array(${$i}, array( 21 CURLOPT_POST => true, 22 CURLOPT_RETURNTRANSFER => true, 23 CURLOPT_POSTFIELDS => http_build_query($params), 24 CURLOPT_HTTPHEADER => $header, 25 CURLOPT_TIMEOUT => $TIMEOUT, 26 CURLOPT_CONNECTTIMEOUT => $TIMEOUT, 27 CURLOPT_VERBOSE => TRUE, 28 )); 29 30 curl_multi_add_handle($mh, ${$i}); 31 $i++; 32} 33 34do { 35 $stat = curl_multi_exec($mh, $running); //multiリクエストスタート 36} while ($stat === CURLM_CALL_MULTI_PERFORM); 37if ( ! $running || $stat !== CURLM_OK) { 38 throw new RuntimeException('リクエストが開始出来なかった。マルチリクエスト内のどれか、URLの設定がおかしいのでは?'); 39} 40 41do switch (curl_multi_select($mh, $TIMEOUT)) { //イベントが発生するまでブロック 42 case -1: //selectに失敗。ありうるらしい。 https://bugs.php.net/bug.php?id=61141 43 usleep(10); //ちょっと待ってからretry。ここも別の処理を挟んでもよい。 44 do { 45 $stat = curl_multi_exec($mh, $running); 46 } while ($stat === CURLM_CALL_MULTI_PERFORM); 47 continue 2; 48 49 case 0: //タイムアウト -> 必要に応じてエラー処理に入るべきかも。 50 continue 2; //ここではcontinueでリトライします。 51 52 default: //どれかが成功 or 失敗した 53 do { 54 $stat = curl_multi_exec($mh, $running); //ステータスを更新 55 } while ($stat === CURLM_CALL_MULTI_PERFORM); 56 57 do if ($raised = curl_multi_info_read($mh, $remains)) { 58 //変化のあったcurlハンドラを取得する 59 $info = curl_getinfo($raised['handle']); 60 echo "$info[url]: $info[http_code]\n"; 61 $response = curl_multi_getcontent($raised['handle']); 62 63 if ($response === false) { 64 //エラー。404などが返ってきている 65 echo 'ERROR!!!', PHP_EOL; 66 } else { 67 //正常にレスポンス取得 68 //戻り値(オブジェクト)からループでデータを取得する 69 $responseXML = simplexml_load_string($response); 70 71 $result_num = count($responseXML->Result); 72 if ($result_num > 0) { 73 $result = $responseXML->Result[0]; 74 array_push($returnList, $result->Status); 75 } 76 } 77 curl_multi_remove_handle($mh, $raised['handle']); 78 curl_close($raised['handle']); 79 } while ($remains); 80 //select前に全ての処理が終わっていたりすると 81 //複数の結果が入っていることがあるのでループが必要 82} while ($running); 83echo 'finished', PHP_EOL; 84curl_multi_close($mh);
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/12/23 05:34