2014-05-12 6 views
3

cURL 요청 시간이 초과 된 것을 감지하려고합니다. 이게 차이가 있다면 curl_multi_exec을 사용하고 있습니까?PHP에서 cURL 시간 초과를 감지합니다.

curl_errno()의 출력은 0으로 성공했음을 나타냅니다.

운전 가

에러 코드가 좋은 이유 어떤 아이디어 수신 -1 바이트에서 0 1,435 밀리 초 후에 타임 아웃하지만, 오류 메시지가 존재한다 : 그러나 curl_error의 출력()은 ? 나는 타임 아웃을 위해 28의 에러 코드를 기대한다.

또한 curl_getinfo()에서 제한 시간 동안 확인할 수있는 것이 있습니까?

PHP 5.4.4/cURL 7.24.0을 사용하고 있습니다.

편집 1 - 샘플 코드 :

$mh = curl_multi_init(); 
curl_multi_add_handle($mh,$a); 
curl_multi_add_handle($mh,$b); 
curl_multi_add_handle($mh,...); 

do { 
    $mrc = curl_multi_exec($mh, $active); 
} while ($mrc == CURLM_CALL_MULTI_PERFORM); 

while ($active && $mrc == CURLM_OK) { 
    if (curl_multi_select($mh) == -1) usleep(100); 
    do { $mrc = curl_multi_exec($mh, $active); } 
    while ($mrc == CURLM_CALL_MULTI_PERFORM); 
} 
+1

당신은 당신의 cURL 코드 – Guns

+0

을 게시 할 수 있습니까? 고마워! – Kit

+0

그 이유가 확실하지 않습니다. 'CURLOPT_CONNECTTIMEOUT' 또는'CURLOPT_CONNECTTIMEOUT_MS'를 사용하여 에러를 강제로 시도하도록 타임 아웃을 지정할 수 있습니다. – ThomasEllis

답변

2

curl_multi_exec()를 사용하여, 특정 핸들에 대한 오류 코드를 얻을 수 curl_multi_info_read()를 사용해야합니다. 이는 PHP가 쉽고 여러 개의 인터페이스에서 cURL과 인터페이스하는 방식과 cURL의 curl_multi_info_read() 함수 (아래 설명 참조)에서 개별 핸들에 오류 코드를 가져 오는 방법 때문입니다.

기본적으로 멀티 핸들을 사용하는 경우 curl_errno()curl_error()은 신뢰할 수 없거나 정확하지 않습니다.

manual에서이 변형 예를 참조하십시오 :

<?php 

$urls = array(
    "http://www.cnn.com/", 
    "http://www.bbc.co.uk/", 
    "http://www.yahoo.com/", 
    'http://wijgeiwojgieowjg.com/', 
    'http://www.example.com/', 
); 

$infos = array(); 

$mh = curl_multi_init(); 

foreach ($urls as $i => $url) { 
    $conn[$i] = curl_init($url); 
    curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER, 1); 

    if (strpos($url, 'example.com') !== false) { 
     // set a really short timeout for one url 
     curl_setopt($conn[$i], CURLOPT_TIMEOUT_MS, 10); 
    } 

    curl_multi_add_handle($mh, $conn[$i]); 
} 

do { 
    $status = curl_multi_exec($mh, $active); 

    if (($info = curl_multi_info_read($mh)) !== false) { 
     $infos[$info['handle']] = $info; 
    } 

} while ($status === CURLM_CALL_MULTI_PERFORM || $active); 

foreach ($urls as $i => $url) { 
    $info = $infos[$conn[$i]]; 

    echo "$url returned code {$info['result']}"; 
    if (version_compare(PHP_VERSION, '5.5.0') >= 0) { 
     echo ": " . curl_strerror($info['result']); 
    } 
    echo "\n"; 

    if ($info['result'] === 0) { 
     $res[$i] = curl_multi_getcontent($conn[$i]); 
    } 

    curl_close($conn[$i]); 
} 

출력 : 0

http://www.bbc.co.uk/ 코드를 반환 0

http://www.yahoo.com/ 코드를 반환

http://www.cnn.com/ 코드 반환 0

http://wijgeiwojgieowjg.com/ 6

http://www.example.com/ 코드 반환 코드 반환 (28)

설명 :

특히,이 PHP의 curl_exec() 호출 방법에 의한 컬의 CURLcode (오류 코드)를 반환 curl_easy_perform 및 PHP는 cURL 옵션 CURLOPT_ERRORBUFFER을 지정하여 버퍼가 자동으로 오류 메시지로 채워지도록합니다.

그러나 PHP의 curl_multi_exec()을 사용하면 PHP는 즉시 반환하는 cURL의 curl_multi_perform을 호출하고 멀티 핸들에 대한 오류 코드를 반환하지 않습니다. cURL의 curl_multi_info_read 함수를 호출하여 개별 핸들에 대한 오류 코드를 가져와야합니다.

PHP 5.5.0은 컬 오류 코드에 해당하는 문자열을 반환하는 cURL의 curl_easy_strerror()에 대한 래퍼를 제공합니다.

+0

감사합니다. 내가 필요한 것. 그러나, 나는 현재'curl_getinfo'를 사용하여 응답 HTTP 코드를 확인합니다. 그러나 이렇게하는 것이 안전하지 않습니까? 간헐적 인 네트워크 문제가 있는지 확인하려고하는데 일부 요청에 대해 500이 반환됩니다. – Kit

+1

'curl_getinfo'를 사용하면 개별 핸들 중 하나에서 정보 (예 : HTTP 응답 코드)를 가져올 수 있습니다. 개별 핸들에'curl_multi_info_read'에서 반환 된 에러 조건이있는 경우 curl_getinfo의 정보 일부 또는 전부를 채우거나 관련시킬 수 없습니다. – drew010

+0

의미가 있습니다. 고맙습니다! – Kit

0

php.net의 문서와 예제가 비동기 컬과 관련하여 정말 좋지 않으므로 디버깅이 정말 힘들 수 있습니다.

위의 같은 주요 작업 루프와
// Main work loop 

do { 
    $mrc = curl_multi_exec($mh, $active); 
} while ($mrc == CURLM_CALL_MULTI_PERFORM); 

while($status = curl_multi_info_read($mh)) { 
    if($status['msg'] == CURLMSG_DONE) { 

     $errno = $status['result']; 
     $errstr = curl_strerror($errno); 

     if($errno == CURLE_OK) { 

      // This request completed successfully 

      // Do something with the info 
      $info = curl_getinfo($status['handle'); 

     } else { 

      // There was an error handling this request, 
      // like a timeout or something. 
      // Note: curl_errno($ch) will probably say success 
      // but it's lying to you. Ignore it. 

      fwrite(STDERR, "Request failed: Error($errno): $errstr\n"); 

     } 
    } 
} 

, 당신은 다음을 호출 할 수 있습니다 많은 시간을 당신이 필요로 : 여기

는 curl_multi_exec에 관해서 작업을 수행 것을 증명하는 데 도움이되는 몇 가지 예제 코드입니다. 뭔가 같은 것

while($this->workRemaining()) { 
    $this->work(); 
    usleep(100); // Sleep, or better yet do something productive 
} 

나는 전체 클래스를 출력하지 않을 것이다. 당신이 원하는대로 할 수 있습니다.

중요한 부분은 $status['result']을 확인하여 오류가 있는지 확인하는 것입니다. multi_curl 환경에서 잘못되었으므로 curl_getinfo($ch)에 의존하지 마십시오.

관련 문제