是否有任何方法来获得头部和主体的cURL请求使用PHP?我发现这个选项:
curl_setopt($ch, CURLOPT_HEADER, true);
会返回body和header,但之后我需要解析它来得到body。有没有办法以更可用(和更安全)的方式同时获得两者?
注意,对于“单个请求”,我的意思是避免在GET/POST之前发出HEAD请求。
是否有任何方法来获得头部和主体的cURL请求使用PHP?我发现这个选项:
curl_setopt($ch, CURLOPT_HEADER, true);
会返回body和header,但之后我需要解析它来得到body。有没有办法以更可用(和更安全)的方式同时获得两者?
注意,对于“单个请求”,我的意思是避免在GET/POST之前发出HEAD请求。
当前回答
以防你不能/不使用CURLOPT_HEADERFUNCTION或其他解决方案;
$nextCheck = function($body) {
return ($body && strpos($body, 'HTTP/') === 0);
};
[$headers, $body] = explode("\r\n\r\n", $result, 2);
if ($nextCheck($body)) {
do {
[$headers, $body] = explode("\r\n\r\n", $body, 2);
} while ($nextCheck($body));
}
其他回答
这就是你想要的吗?
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
$response = curl_exec($ch);
list($header, $body) = explode("\r\n\r\n", $response, 2);
如果你特别想要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);
杰弗里回答的改进:
我不能得到正确的长度头部与$headerSize = curl_getinfo($this->curlHandler, CURLINFO_HEADER_SIZE);-我必须计算头部大小我自己。
此外,为了提高可读性,还做了一些改进。
$headerSize = 0;
curl_setopt_array($this->curlHandler, [
CURLOPT_URL => $yourUrl,
CURLOPT_POST => 0,
CURLOPT_RETURNTRANSFER => 1,
// this function is called by curl for each header received
CURLOPT_HEADERFUNCTION =>
function ($curl, $header) use (&$headers, &$headerSize) {
$lenghtCurrentLine = strlen($header);
$headerSize += $lenghtCurrentLine;
$header = explode(':', $header, 2);
if (count($header) > 1) { // store only vadid headers
$headers[strtolower(trim($header[0]))][] = trim($header[1]);
}
return $lenghtCurrentLine;
},
]);
$fullResult = curl_exec($this->curlHandler);
$result = substr($fullResult, $headerSize);
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);
上面的工作与一切,不同的协议和代理,你不需要担心头部的大小,或设置许多不同的卷曲选项。
注:要用object方法处理标题行,请这样做:
curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($object, 'methodName'))
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_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的回答可能会更可靠地处理这些问题。