PHP cURL은 단일 요청으로 응답 헤더와 본문을 검색 할 수 있습니까?
PHPPHP cURL은 단일 요청으로 응답 헤더와 본문을 검색 할 수 있습니까?
PHP를 사용하여 cURL 요청을 위해 헤더와 본문을 모두 얻을 수있는 방법이 있습니까? 나는이 옵션을 발견 :
curl_setopt($ch, CURLOPT_HEADER, true);
본문과 머리글을 반환 할 것이지만, 그 다음 본문을 가져 오기 위해 구문 분석해야합니다. 더 유용한 (그리고 안전한) 방법으로 둘 다 얻을 수있는 방법이 있습니까?
"단일 요청"의 경우 GET / POST 이전에 HEAD 요청을 피하는 것을 의미합니다.
해결법
-
==============================
1.이에 대한 한 가지 해결책은 PHP 문서 주석에 게시되었습니다. http://www.php.net/manual/en/function.curl-exec.php#80442
이에 대한 한 가지 해결책은 PHP 문서 주석에 게시되었습니다. http://www.php.net/manual/en/function.curl-exec.php#80442
코드 예 :
$ch = curl_init(); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_VERBOSE, 1); curl_setopt($ch, CURLOPT_HEADER, 1); // ... $response = curl_exec($ch); // Then, after your curl_exec call: $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $header = substr($response, 0, $header_size); $body = substr($response, $header_size);
경고 : 아래의 설명에서 언급했듯이 프록시 서버와 함께 사용하거나 특정 유형의 리디렉션을 처리 할 때 신뢰할 수 없습니다. @ Geoffrey의 답변이 더 안정적으로 처리 할 수 있습니다.
-
==============================
2.Curl에는 CURLOPT_HEADERFUNCTION이라는 내장 옵션이 있습니다. 이 옵션의 값은 콜백 함수의 이름이어야합니다. Curl은 헤더 (및 헤더 만!)를이 콜백 함수에 줄 단위로 전달합니다 (따라서 헤더 섹션의 맨 위에서 시작하여 각 헤더 행에 대해 함수가 호출됩니다). 그런 다음 콜백 함수는 모든 작업을 수행 할 수 있으며 주어진 행의 바이트 수를 반환해야합니다. 다음은 테스트 된 작업 코드입니다.
Curl에는 CURLOPT_HEADERFUNCTION이라는 내장 옵션이 있습니다. 이 옵션의 값은 콜백 함수의 이름이어야합니다. Curl은 헤더 (및 헤더 만!)를이 콜백 함수에 줄 단위로 전달합니다 (따라서 헤더 섹션의 맨 위에서 시작하여 각 헤더 행에 대해 함수가 호출됩니다). 그런 다음 콜백 함수는 모든 작업을 수행 할 수 있으며 주어진 행의 바이트 수를 반환해야합니다. 다음은 테스트 된 작업 코드입니다.
function HandleHeaderLine( $curl, $header_line ) { echo "<br>YEAH: ".$header_line; // or do whatever return strlen($header_line); } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "http://www.google.com"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADERFUNCTION, "HandleHeaderLine"); $body = curl_exec($ch);
위의 모든 것은 다른 프로토콜과 프록시에서도 작동합니다. 헤더 크기에 대해 걱정할 필요가 없으며 다양한 컬 옵션을 설정해야합니다.
P.S. : 객체 메소드를 사용하여 헤더 행을 처리하려면 다음을 수행하십시오.
curl_setopt($ch, CURLOPT_HEADERFUNCTION, array(&$object, 'methodName'))
-
==============================
3.이 스레드가 제공하는 다른 솔루션 중 많은 것이 올바르게 수행되지 않습니다.
이 스레드가 제공하는 다른 솔루션 중 많은 것이 올바르게 수행되지 않습니다.
가장 올바른 방법은 CURLOPT_HEADERFUNCTION을 사용하는 것입니다.
다음은 PHP 클로저를 사용하여 이것을 수행하는 매우 깨끗한 메소드입니다. 또한 서버와 HTTP 버전간에 일관된 처리를 위해 모든 헤더를 소문자로 변환합니다.
이 버전은 중복 된 헤더를 유지합니다.
이것은 RFC 822 및 RFC 2616을 준수합니다. mb_string 함수를 사용하기 위해 편집을 제안하지 마십시오. 잘못된 것입니다!
$ch = curl_init(); $headers = []; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // this function is called by curl for each header received curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($curl, $header) use (&$headers) { $len = strlen($header); $header = explode(':', $header, 2); if (count($header) < 2) // ignore invalid headers return $len; $name = strtolower(trim($header[0])); if (!array_key_exists($name, $headers)) $headers[$name] = [trim($header[1])]; else $headers[$name][] = trim($header[1]); return $len; } ); $data = curl_exec($ch); print_r($headers);
-
==============================
4.너는 무엇을보고 있니?
너는 무엇을보고 있니?
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); $response = curl_exec($ch); list($header, $body) = explode("\r\n\r\n", $response, 2);
-
==============================
5.그냥 옵션을 설정하십시오 :
그냥 옵션을 설정하십시오 :
curl_getinfo를 CURLINFO_HTTP_CODE (또는 opt 매개 변수 없음)와 함께 사용하면 원하는 모든 정보가 포함 된 연관 배열이됩니다.
더보기 : http://php.net/manual/fr/function.curl-getinfo.php
-
==============================
6.특별히 Content-Type을 원한다면 검색 할 수있는 특별한 cURL 옵션이 있습니다.
특별히 Content-Type을 원한다면 검색 할 수있는 특별한 cURL 옵션이 있습니다.
$ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $response = curl_exec($ch); $content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
-
==============================
7.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_VERBOSE, 1); curl_setopt($ch, CURLOPT_HEADER, 1); $parts = explode("\r\n\r\nHTTP/", $response); $parts = (count($parts) > 1 ? 'HTTP/' : '').array_pop($parts); list($headers, $body) = explode("\r\n\r\n", $parts, 2);
HTTP / 1.1 작동 100 다른 헤더보다 먼저 계속하십시오.
줄 바꿈으로 CRLF 대신 LF 만 보내는 버그가있는 서버에서 작업해야하는 경우 다음과 같이 preg_split을 사용할 수 있습니다.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_VERBOSE, 1); curl_setopt($ch, CURLOPT_HEADER, 1); $parts = preg_split("@\r?\n\r?\nHTTP/@u", $response); $parts = (count($parts) > 1 ? 'HTTP/' : '').array_pop($parts); list($headers, $body) = preg_split("@\r?\n\r?\n@u", $parts, 2);
-
==============================
8.내 길은 ~이다.
내 길은 ~이다.
$response = curl_exec($ch); $x = explode("\r\n\r\n", $v, 3); $header=http_parse_headers($x[0]); if ($header=['Response Code']==100){ //use the other "header" $header=http_parse_headers($x[1]); $body=$x[2]; }else{ $body=$x[1]; }
필요한 경우 for 루프를 적용하고 분해 한계를 제거하십시오.
-
==============================
9.여기에 많은 해답이있는 문제는 "\ r \ n \ r \ n"이 html 본문에 합법적으로 나타날 수 있기 때문에 헤더를 올바르게 분할하지 못한다는 것입니다.
여기에 많은 해답이있는 문제는 "\ r \ n \ r \ n"이 html 본문에 합법적으로 나타날 수 있기 때문에 헤더를 올바르게 분할하지 못한다는 것입니다.
curl_exec에 대한 하나의 호출로 헤더를 별도로 저장하는 유일한 방법은 https://stackoverflow.com/a/25118032/3326494에서 위에 제안 된 콜백을 사용하는 것입니다.
그런 다음 (확실하게) 요청 본문을 가져 오려면 Content-Length 헤더 값을 음수 시작 값으로 substr ()에 전달해야합니다.
-
==============================
10.서버에서 반환 된 마지막 물건이 필요할 때 조심하십시오. 이 코드는 실제 (마지막) 헤더와 본문을 기다리는 동안 기대치를 낮출 수 있습니다. list ($ headers, $ body) = explode ( "\ r \ n \ r \ n", $ result, 2);
서버에서 반환 된 마지막 물건이 필요할 때 조심하십시오. 이 코드는 실제 (마지막) 헤더와 본문을 기다리는 동안 기대치를 낮출 수 있습니다. list ($ headers, $ body) = explode ( "\ r \ n \ r \ n", $ result, 2);
여기에 최종 헤더 및 본문 부분을 가져 오는 간단한 방법이 있습니다.
$result = explode("\r\n\r\n", $result); // drop redirect etc. headers while (count($result) > 2) { array_shift($result); } // split headers / body parts @ list($headers, $body) = $result;
-
==============================
11.참조 매개 변수를 사용하여 응답 헤더를 반환합니다.
참조 매개 변수를 사용하여 응답 헤더를 반환합니다.
<?php $data=array('device_token'=>'5641c5b10751c49c07ceb4', 'content'=>'测试测试test' ); $rtn=curl_to_host('POST', 'http://test.com/send_by_device_token', array(), $data, $resp_headers); echo $rtn; var_export($resp_headers); function curl_to_host($method, $url, $headers, $data, &$resp_headers) {$ch=curl_init($url); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $GLOBALS['POST_TO_HOST.LINE_TIMEOUT']?$GLOBALS['POST_TO_HOST.LINE_TIMEOUT']:5); curl_setopt($ch, CURLOPT_TIMEOUT, $GLOBALS['POST_TO_HOST.TOTAL_TIMEOUT']?$GLOBALS['POST_TO_HOST.TOTAL_TIMEOUT']:20); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); curl_setopt($ch, CURLOPT_HEADER, 1); if ($method=='POST') {curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); } foreach ($headers as $k=>$v) {$headers[$k]=str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $k)))).': '.$v; } curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $rtn=curl_exec($ch); curl_close($ch); $rtn=explode("\r\n\r\nHTTP/", $rtn, 2); //to deal with "HTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK...\r\n\r\n..." header $rtn=(count($rtn)>1 ? 'HTTP/' : '').array_pop($rtn); list($str_resp_headers, $rtn)=explode("\r\n\r\n", $rtn, 2); $str_resp_headers=explode("\r\n", $str_resp_headers); array_shift($str_resp_headers); //get rid of "HTTP/1.1 200 OK" $resp_headers=array(); foreach ($str_resp_headers as $k=>$v) {$v=explode(': ', $v, 2); $resp_headers[$v[0]]=$v[1]; } return $rtn; } ?>
-
==============================
12.curl을 사용할 필요가 없다면;
curl을 사용할 필요가 없다면;
$body = file_get_contents('http://example.com'); var_export($http_response_header); var_export($body);
어느 출력
array ( 0 => 'HTTP/1.0 200 OK', 1 => 'Accept-Ranges: bytes', 2 => 'Cache-Control: max-age=604800', 3 => 'Content-Type: text/html', 4 => 'Date: Tue, 24 Feb 2015 20:37:13 GMT', 5 => 'Etag: "359670651"', 6 => 'Expires: Tue, 03 Mar 2015 20:37:13 GMT', 7 => 'Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT', 8 => 'Server: ECS (cpm/F9D5)', 9 => 'X-Cache: HIT', 10 => 'x-ec-custom-error: 1', 11 => 'Content-Length: 1270', 12 => 'Connection: close', )'<!doctype html> <html> <head> <title>Example Domain</title>...
http://php.net/manual/en/reserved.variables.httpresponseheader.php를 참조하십시오.
from https://stackoverflow.com/questions/9183178/can-php-curl-retrieve-response-headers-and-body-in-a-single-request by cc-by-sa and MIT license
'PHP' 카테고리의 다른 글
오류 및 경고를 파일에 기록하는 방법 (0) | 2018.09.08 |
---|---|
어떻게 PHP로 HTML을 되풀이 할 수 있습니까? (0) | 2018.09.08 |
PHP 포함 파일에 직접 액세스하지 못하게합니다. (0) | 2018.09.08 |
Laravel에는 Mcrypt PHP 확장이 필요합니다. (0) | 2018.09.08 |
"Keep Me Logged In"- 최선의 접근 방식 (0) | 2018.09.08 |