PHP curl_multi_thread无法正常工作

时间:2018-11-13 22:59:32

标签: php curl curl-multi

这是我正在使用的代码

function initiate_curl($row, $mh) {
    $ch = curl_init();
    $url = 'http://openapi.gbis.go.kr/ws/rest/busarrivalservice'; /*URL*/
    $queryParams = '?' . urlencode('serviceKey') . "SERVICE API KEY"; /*Service Key*/
    $queryParams .= '&' . urlencode('stationId') . '=' . urlencode($row['stId']); /**/
    $queryParams .= '&' . urlencode('routeId') . '=' . urlencode($row['busRouteId']); /*노선ID*/
    $queryParams .= '&' . urlencode('staOrder') . '=' . urlencode($row['seq']);

    curl_setopt($ch, CURLOPT_URL, $url . $queryParams);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_HEADER, FALSE);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

    curl_multi_add_handle($mh, $ch);
    return $ch;

}

$mh = curl_multi_init();
$arr = array();
$rows = array();

while ($row = mysqli_fetch_array($query)) {
    array_push($arr, initiate_curl($row, $mh));
    array_push($rows, $row);
}
$running = null;
do {
  curl_multi_exec($mh, $running);
} while ($running);

foreach($arr as $curl) {curl_multi_remove_handle($mh, $curl);}
curl_multi_close($mh);
foreach($arr as $key=>$curl) {
    **DO MY WORK
}

在大多数情况下,它可以正常工作,但有时由于查询的结果而为空。但是,当我通过键入URL进入API时,它将完美地返回该值。另外,返回为null的对象随时都会更改,因此我100%确信这是我curl_multi部分的错。

我实现了这个错误,还是使用起来不那么可靠?

1 个答案:

答案 0 :(得分:0)

(这不是答案,但太多了,不能发表为评论)

首先,这是在PHP中编写URL编码查询字符串的一种卑鄙的方式:

$queryParams = '?' . urlencode('serviceKey') . "SERVICE API KEY"; /*Service Key*/
$queryParams .= '&' . urlencode('stationId') . '=' . urlencode($row['stId']); /**/
$queryParams .= '&' . urlencode('routeId') . '=' . urlencode($row['busRouteId']); /*노선ID*/
$queryParams .= '&' . urlencode('staOrder') . '=' . urlencode($row['seq']);

PHP具有专门用于编写URL编码的查询字符串的功能,称为http_build_query,如果编写为:

$queryParams = http_build_query(array(
    'serviceKey' => 'SERVICE API KEY',
    'stationId' => $row['stId'],
    'routeId' => $row['busRouteId'],
    'staOrder' => $row['seq']
));

另外,curl_multi_exec是一个异步函数,它将在curl等待io时立即返回,这意味着调用curl_multi_exec直到$ running变为false将使用100%cpu(1个cpu内核),这是完全不必要的,并且一些共享的Web主机提供程序甚至可能因为使用过多的CPU而杀死您的脚本。使用curl_multi_select进行睡眠,直到curl_multi_exec有事可做(这会将CPU使用率降低到1-2%,而不是100%),试试这个:

$running = null;
for(;;){
  curl_multi_exec($mh, $running);
  if(!$running){
     break;
  }
  curl_multi_select($mh);
}
  

有时我的查询结果为空

您在说什么查询?您的意思是从mysql查询中获取NULL?例如,mysqli_fetch_array有时返回NULL?在这种情况下,您需要检查mysqli_fetch_array的实现,它不是标准的PHP函数,而是userland-php代码。 (但是,类似的名称mysqli_result::fetch_array是一个普通的核心PHP函数,当该函数返回NULL时,意味着您已经获取了最后一个结果;或者,如果它在第一次执行时返回NULL,则表明存在共0个结果)