0

This is the code I am using

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
}

Most of the times it works fine but sometimes I get null as a result of the query. However, when I go to the API through typing the url, it returns the value perfectly. Also, the object that is returned as null changes any time so I'm 100% sure that this is the fault of my curl_multi part.

Am I implementing this wrong or is it simply not that reliable to use?

  • there is a much better way to write that url with the http_build_query function, check this: https://pastebin.com/raw/xjEJAGqr – hanshenrik Nov 14 '18 at 00:19
  • the url is fine I'm having problems fetching the data – Seong Min Choo Nov 14 '18 at 00:21
  • also your curl_multi_exec loop will use 100% cpu (of 1 core) for no good reason, add a curl_multi_select in there to keep your cpu usage reasonable – hanshenrik Nov 14 '18 at 00:22
  • add CURLOPT_VERBOSE logging to each curl handle, and when you get a NULL, dump the verbose log of that curl handle, and post the verbose log, the log may say why it returned null – hanshenrik Nov 14 '18 at 00:26
  • can you explain more on that sir? I am not that familiar with php.. – Seong Min Choo Nov 14 '18 at 00:31

1 Answers1

0

(this is not an answer, but too much to be posted as comments)

first off, this is a shitty way to write a URL-encoded query string in PHP:

$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 has a function specifically dedicated to writing URL-encoded query strings, called http_build_query, and the code would look much better if written as:

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

also, curl_multi_exec is an async function, it will return as soon as curl is waiting for io, meaning that calling curl_multi_exec until $running becomes false will use 100% cpu (of 1 cpu core), which is completely unnecessary, and some shared-webhost providers may even kill your script for using too much cpu .. use curl_multi_select to sleep until curl_multi_exec has something to do (which will turn the CPU usage down to 1-2% instead of 100%), try this:

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

sometimes I get null as a result of the query

what query are you talking about? do you mean you get NULL from the mysql query? eg that mysqli_fetch_array sometimes return NULL? in which case you need to check out the implementation of mysqli_fetch_array, it's not a standard PHP function, it's userland-php code. (however, the similarly named mysqli_result::fetch_array is a normal core PHP function, and when that function returns NULL, it means you've already fetched the last result - or if it returns NULL on the first execution, it means there was 0 results in total)

hanshenrik
  • 19,904
  • 4
  • 43
  • 89