PHP에서 컬 타임 아웃 설정


230

PHP를 통해 eXist 데이터베이스에서 curl 요청을 실행하고 있습니다. 데이터 집합이 매우 커서 결과적으로 데이터베이스가 XML 응답을 반환하는 데 오랜 시간이 걸립니다. 이를 해결하기 위해 긴 시간 초과로 컬 요청을 설정했습니다.

$ch = curl_init();
$headers["Content-Length"] = strlen($postString);
$headers["User-Agent"] = "Curl/1.0";

curl_setopt($ch, CURLOPT_URL, $requestUrl);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'admin:');
curl_setopt($ch,CURLOPT_TIMEOUT,1000);
$response = curl_exec($ch);
curl_close($ch);

그러나 컬 요청은 요청이 완료되기 전에 지속적으로 종료됩니다 (브라우저를 통해 요청하면 1000 미만). 컬이 타임 아웃을 설정하는 올바른 방법인지 아는 사람이 있습니까?

답변:


346

설명서를 참조하십시오 : http://www.php.net/manual/en/function.curl-setopt.php

CURLOPT_CONNECTTIMEOUT-연결하는 동안 대기하는 시간 (초)입니다. 무기한 대기하려면 0을 사용하십시오.
CURLOPT_TIMEOUT-cURL 함수를 실행할 수있는 최대 시간 (초)입니다.

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0); 
curl_setopt($ch, CURLOPT_TIMEOUT, 400); //timeout in seconds

또한 PHP 스크립트 자체의 시간 실행을 늘리는 것을 잊지 마십시오.

set_time_limit(0);// to infinity for example

13
set_time_limit(0);스크립트가 콘솔에서 실행중인 경우 필요하지 않습니다 .
— CONvid19

6
@PedroLobito 언급 한 것은 cli에있는 PHP의 기본 구성이지만 이것이 수정되었을 수 있습니다.
— cherouvim

4
@cherouvim은 여기에 분명히 정확합니다 (실행 php -d max_execution_time=1 -r 'while(true){$r=1*1;}'중이거나 cli에 마법의 '항상 무제한'플래그가 없음을 관찰해야합니다.
— Wrikken

@Pedro Lobito set_time_limit(0)루프 내부에서 사용 하지 않는다면 필요하지 않습니다 .
— Viktor Joras

58

흠, 그것은 CURLOPT_TIMEOUTcURL 함수가 실행하는 데 걸리는 시간을 정의하는 것처럼 보입니다 . CURLOPT_CONNECTTIMEOUTcURL에 연결이 완료되기를 기다리는 최대 시간을 알려주기 때문에 실제로 대신 보고 있어야한다고 생각합니다 .


그동안 PHP에서 워드 프로세서 말은 CURLOPT_TIMEOUT함수가 걸리는 시간에 관한이의 기본 컬 라이브러리 워드 프로세서 는 요청이 흥미 구별되는, 걸리는 시간에 대해 말할 것 - 확실하지 않은 어떤 방법으로 그것을 읽을 수 있습니다!
— fideloper

여기 생각하는 최고의 해석 : stackoverflow.com/questions/27776129/...
— fideloper

33

PHP docs 주석에서 일부 사람들과 관련이있을 수있는 단점이 있습니다.

cURL이 1 초 이내에 시간 초과되도록하려면 CURLOPT_TIMEOUT_MS"Unix-like systems"에 버그 / "기능"이 있지만 "cURL 오류가 발생하여 값이 <1000ms 인 경우 libcurl이 즉시 시간 초과되도록하는 버그 / 기능이 있습니다. 오류 (28) : 시간이 초과되었습니다 " 이 동작에 대한 설명은 다음과 같습니다.

"libcurl이 표준 시스템 이름 확인자를 사용하도록 구축 된 경우, 전송의 해당 부분은 최소 1 초의 시간 초과가 허용되는 시간 초과에 대해 여전히 전체 초 해상도를 사용합니다."

이것이 PHP 개발자에게 의미하는 바는 "libcurl이 표준 시스템 이름 확인자를 사용하고 있는지 알 수 없기 때문에 먼저 테스트하지 않고는이 기능을 사용할 수 없습니다."

문제는 (Li | U) nix에서 libcurl이 표준 이름 확인자를 사용할 때 libcurl이 시간 초과 경보라고 생각하는 이름 확인 중에 SIGALRM이 발생한다는 것입니다.

해결책은 CURLOPT_NOSIGNAL을 사용하여 신호를 비활성화하는 것입니다. 다음은 시간 초과를 테스트 할 수 있도록 10 초 지연을 발생시키는 자체 요청 스크립트 예입니다.

if (!isset($_GET['foo'])) {
    // Client
    $ch = curl_init('http://localhost/test/test_timeout.php?foo=bar');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200);
    $data = curl_exec($ch);
    $curl_errno = curl_errno($ch);
    $curl_error = curl_error($ch);
    curl_close($ch);

    if ($curl_errno > 0) {
        echo "cURL Error ($curl_errno): $curl_error\n";
    } else {
        echo "Data received: $data\n";
    }
} else {
    // Server
    sleep(10);
    echo "Done.";
}

에서 http://www.php.net/manual/en/function.curl-setopt.php#104597


안녕하세요,이 코드는 작동하지만 소스 파일은 7MB이며이 다운로드는 52KB 만 가능합니다. 무엇이 잘못 될 수 있습니까? URL은 webserver.tld / folder / download /…
— Muflix

@Simon East 당신은 저를 도와주세요 stackoverflow.com/questions/30861112/…
— Nathan Srivi 2016 년

이 스크립트에서 시간 종료 오류 가 예상 됩니다.
— kmoney12

30

코드는 시간 초과를 1000 초로 설정합니다 . 밀리 초의 경우을 사용하십시오 CURLOPT_TIMEOUT_MS.


13

귀하와 파일 사이의 시간 종료에 대해 확인해야합니다. 이 경우 PHP와 컬.

전송이 여전히 활성화되어있을 때, 당신은 설정해야 타임 아웃 않으려면 컬에게 CURLOPT_TIMEOUT로 0대신 1000.

curl_setopt($ch, CURLOPT_TIMEOUT, 0);

PHP에서도 시간 제한을 제거해야합니다. 그렇지 않으면 자체적으로 (기본적으로 30 초 후) Curl의 요청에 따라 스크립트가 종료됩니다. 이것만으로도 문제가 해결 될 것 입니다.
또한 데이터 무결성이 필요한 경우 다음을 사용하여 보안 계층을 추가 할 수 있습니다 ignore_user_abort.

# The maximum execution time, in seconds. If set to zero, no time limit is imposed.
set_time_limit(0);

# Make sure to keep alive the script when a client disconnect.
ignore_user_abort(true);

클라이언트 연결이 끊어지면 스크립트 실행이 중단되고 데이터가 손상 될 수 있습니다 (
예 : 비 임시 데이터베이스 쿼리, 구성 파일 작성 등의 경우 부분 파일을 다운로드 할 것입니다 ...

이 스레드는 엔진 검색에서 맨 위에 있기 때문에이 이전 질문에 응답합니다 CURL_TIMEOUT.


8

브라우저에서 요청을 실행할 수 없으며 CURL 요청을 실행하는 서버가 응답하기를 기다리는 시간이 초과됩니다. 브라우저가 기본 네트워크 시간 제한 인 1-2 분 후에 시간 초과 될 수 있습니다.

명령 행 / 터미널에서 실행해야합니다.


2
+1-타임 아웃이 컬 외부에있을 수 있습니다. 실제로 정기적으로 무언가를 출력하여 브라우저 시간 초과를 해결할 수 있습니다. 브라우저는 일반적으로 더 많은 데이터를 수신 할 때마다 시간 초과를 재설정합니다. 그러나 그것은 해킹입니다. CLI를 통한 실행은 (거의?) 항상 선호됩니다.
— Frank Farmer

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.