풀 URL 사용 시 PHP file_get_contents가 매우 느리다
HTML 페이지에서 PDF 파일을 생성하는 스크립트(원래 작성하지 않은 스크립트)를 사용하고 있습니다.문제는 처리 시간이 1-2분 정도로 매우 오래 걸린다는 것입니다.처음에는 잘 작동했지만 지난 몇 주 동안 속도가 느려졌습니다.
스크립트가 호출합니다.file_get_contents
php 스크립트에서 결과를 서버의 HTML 파일로 출력하고 해당 파일에서 pdf generator 앱을 실행합니다.
나는 문제를 좁힌 것 같다.file_get_contents
로컬 패스가 아닌 풀 URL로 콜합니다.
사용할 때
$content = file_get_contents('test.txt');
거의 순식간에 처리됩니다.그러나 전체 URL을 사용하는 경우
$content = file_get_contents('http://example.com/test.txt');
처리에 걸리는 시간은 30~90초입니다.
서버에만 국한된 것이 아니라 http://www.google.com 등의 외부 URL에 접속할 때 속도가 느립니다.로컬에서 파일을 호출하면 작동하지 않는 쿼리 문자열 변수가 있기 때문에 스크립트가 풀 URL을 호출한다고 생각합니다.
나도 노력했어fopen
,readfile
,그리고.curl
모두 마찬가지로 느렸습니다.이 문제를 해결할 방법이 없을까요?
주의: 이것은 PHP 5.6.14에서 수정되었습니다.a
Connection: close
HTTP/1.0 요구에서도 헤더는 자동적으로 송신됩니다.「commit」를 참조해 주세요.
file_get_contents 스크립트가 느린 원인을 파악하는데 어려움을 겪었습니다.
Wireshark를 사용하여 분석한 결과 리모트 웹 서버가 TCP 접속을 15초까지 닫지 않는 문제(즉, "킵얼라이브")가 있었습니다.
실제로 file_get_contents는 "connection" HTTP 헤더를 전송하지 않으므로 원격 웹 서버는 기본적으로 이것이 keep-alive 연결이라고 간주하고 15초까지 TCP 스트림을 닫지 않습니다(표준값이 아닐 수 있습니다.서버의 conf에 따라 다릅니다).
일반 브라우저에서는 HTTP 페이로드 길이가 응답 Content-Length HTTP 헤더로 지정된 길이에 도달하면 페이지가 완전히 로드된 것으로 간주됩니다.file_get_contents는 이 기능을 하지 않기 때문에 유감입니다.
솔루션
솔루션을 알고 싶으시면 다음과 같이 하십시오.
$context = stream_context_create(array('http' => array('header'=>'Connection: close\r\n')));
file_get_contents("http://www.something.com/somepage.html",false,$context);
다운로드가 완료되면 접속을 닫도록 리모트 웹 서버에 지시하는 것 뿐입니다.file_get_contents는 응답 Content-Length HTTP 헤더를 사용하여 직접 접속할 수 있을 만큼 인텔리전트하지 않기 때문입니다.
외부 콘텐츠를 가져오려면 curl()을 사용합니다.이거는 Curl()보다 훨씬 빠르기 때문입니다.file_get_contents
해결될지는 볼 .이것으로 문제가 해결될지는 모르겠지만 시도해 볼 만합니다.
또, 서버의 속도는, 파일 취득에 걸리는 시간에 영향을 주는 것에 주의해 주세요.
다음은 사용 예를 제시하겠습니다.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://example.com/test.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
서버의 DNS가 너무 느리기 때문에 다음과 같이 시도해 보십시오.
교체하다
echo file_get_contents('http://www.google.com');
~하듯이
$context=stream_context_create(array('http' => array('header'=>"Host: www.google.com\r\n")));
echo file_get_contents('http://74.125.71.103', false, $context);
나도 같은 문제가 있었어
은, 「타임 을 「타임 아웃」으로 입니다.$options
manager.manager로 하다
$options = array(
'http' => array(
'header' => implode($headers, "\r\n"),
'method' => 'POST',
'content' => '',
'timeout' => .5
),
);
$context = stream_context_create(array('http' => array('header'=>'Connection: close\r\n')));
$string = file_get_contents("http://localhost/testcall/request.php",false,$context);
시간: 50976 ms (총 5회 시도 소요 시간)
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, "http://localhost/testcall/request.php");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
echo $data = curl_exec($ch);
curl_close($ch);
시간: 46679 ms (총 5회 시도 소요 시간)
주의: 요청.php는 mysql 데이터베이스에서 데이터를 가져오는 데 사용됩니다.
명령줄에서 서버의 URL을 가져올 수 있습니까?컬이나 웨젯이 떠오릅니다.통상적인 속도로 URL을 취득하는 경우는, 네트워크상의 문제가 아니고, apache/php 셋업의 문제일 가능성이 높습니다.
API를 API를 file_get_contents
60초 정도 걸렸어요그러나 KrisWebDev의 솔루션을 사용하면 약 25초가 소요되었습니다.
$context = stream_context_create(array('https' => array('header'=>'Connection: close\r\n')));
file_get_contents($url,false,$context);
Curl을 사용할 때 고려해야 할 점은 요청을 "스레드"할 수 있다는 것입니다.현재 스레드화가 가능한 PHP 버전에 액세스할 수 없기 때문에 이것은 저에게 큰 도움이 되었습니다.
예를 들어 리모트 서버에서 file_get_contents를 사용하여7개의 이미지를 가져오고 있었는데 요청당 2~5초 정도 걸렸습니다.사용자가 PDF가 생성되기를 기다리는 동안 이 프로세스만 해도 프로세스에 30초 정도의 시간이 더 걸렸습니다.
이것에 의해, 말 그대로 약 1매의 이미지로 시간이 단축되었습니다.또 다른 예에서는 36개의 URL을 1개 실행하는 데 소요된 시간에 검증합니다.무슨 말인지 알 것 같아. :-)
$timeout = 30;
$retTxfr = 1;
$user = '';
$pass = '';
$master = curl_multi_init();
$node_count = count($curlList);
$keys = array("url");
for ($i = 0; $i < $node_count; $i++) {
foreach ($keys as $key) {
if (empty($curlList[$i][$key])) continue;
$ch[$i][$key] = curl_init($curlList[$i][$key]);
curl_setopt($ch[$i][$key], CURLOPT_TIMEOUT, $timeout); // -- timeout after X seconds
curl_setopt($ch[$i][$key], CURLOPT_RETURNTRANSFER, $retTxfr);
curl_setopt($ch[$i][$key], CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch[$i][$key], CURLOPT_USERPWD, "{$user}:{$pass}");
curl_setopt($ch[$i][$key], CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($master, $ch[$i][$key]);
}
}
// -- get all requests at once, finish when done or timeout met --
do { curl_multi_exec($master, $running); }
while ($running > 0);
그런 다음 결과를 확인합니다.
if ((int)curl_getinfo($ch[$i][$key], CURLINFO_HTTP_CODE) > 399 || empty($results[$i][$key])) {
unset($results[$i][$key]);
} else {
$results[$i]["options"] = $curlList[$i]["options"];
}
curl_multi_remove_handle($master, $ch[$i][$key]);
curl_close($ch[$i][$key]);
그런 다음 파일을 닫습니다.
curl_multi_close($master);
나는 그것이 오래된 질문인 것을 알지만 나는 오늘 그것을 발견했고 답변은 나에게 효과가 없었다.IP당 최대 연결 수를 1로 설정할 수 있다고 말하는 사람은 없습니다.그러면 API 요청을 하고 API는 풀 URL을 사용하기 때문에 다른 요청을 합니다.그렇기 때문에 디스크에서 직접 로딩할 수 있습니다.문제를 해결한 나에게:
if (strpos($file->url, env('APP_URL')) === 0) {
$url = substr($file->url, strlen(env('APP_URL')));
} else {
$url = $file->url;
}
return file_get_contents($url);
언급URL : https://stackoverflow.com/questions/3629504/php-file-get-contents-very-slow-when-using-full-url
'source' 카테고리의 다른 글
Laravel 5.1에서 Laravel 5.8로 업그레이드한 후 whereHas()가 느려짐 (0) | 2022.11.19 |
---|---|
날짜 문자열이 해당 형식의 유효한 날짜인지 확인 (0) | 2022.11.19 |
휴지 상태 주석 - 필드 액세스와 속성 액세스 중 어느 쪽이 더 좋습니까? (0) | 2022.11.19 |
javascript(또는 jQuery) 사용 후 :: before 및 :: 등의 CSS 유사 요소 선택 및 조작 (0) | 2022.11.18 |
LIMIT 오프셋에서 MySQL 함수를 사용할 수 있습니까? (0) | 2022.11.18 |