PHP cURL 可以在单个请求中检索响应标头和正文吗?
有没有办法使用PHP获取cURL请求的标头和正文?我发现这个选项:
curl_setopt($ch, CURLOPT_HEADER, true);
将返回正文加标头,但随后我需要解析它以获取正文。有没有办法以更可用(和安全)的方式获得两者?
请注意,对于“单个请求”,我的意思是避免在GET / POST之前发出HEAD请求。
有没有办法使用PHP获取cURL请求的标头和正文?我发现这个选项:
curl_setopt($ch, CURLOPT_HEADER, true);
将返回正文加标头,但随后我需要解析它以获取正文。有没有办法以更可用(和安全)的方式获得两者?
请注意,对于“单个请求”,我的意思是避免在GET / POST之前发出HEAD请求。
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的答案可能会更可靠地处理这些问题。
此线程提供的许多其他解决方案未正确执行此操作。
\r\n\r\n
CURLOPT_FOLLOWLOCATION
\n
\r
CURLINFO_HEADER_SIZE
最正确的方法是使用CURLOPT_HEADERFUNCTION
。
这是一个使用PHP闭包执行此操作的非常干净的方法。它还将所有标头转换为小写,以便在服务器和 HTTP 版本之间进行一致的处理。
此版本将保留重复的标头
这符合RFC822和RFC2616,请不要使用mb_
(和类似)字符串函数,这不仅是不正确的,甚至是RFC-7230的安全问题!
$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;
$headers[strtolower(trim($header[0]))][] = trim($header[1]);
return $len;
}
);
$data = curl_exec($ch);
print_r($headers);