是否有任何方法来获得头部和主体的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请求。
当前回答
杰弗里回答的改进:
我不能得到正确的长度头部与$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_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在其他报头之前继续。
如果你需要使用错误服务器,只发送LF而不是CRLF作为换行符,你可以使用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);
这里的许多答案的问题是“\r\n\r\n”可以合法地出现在html的主体中,因此您不能确保正确地分割了头文件。
在调用curl_exec时单独存储标头的唯一方法似乎是使用回调,就像上面https://stackoverflow.com/a/25118032/3326494中建议的那样
然后,为了(可靠地)获得请求的主体,您需要将Content-Length报头的值作为负起始值传递给substr()。
我的方法是
$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循环并移除爆炸限制。
如果你特别想要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);
只需设置选项:
CURLOPT_HEADER, 0岁 CURLOPT_RETURNTRANSFER, 1
并使用curl_getinfo与CURLINFO_HTTP_CODE(或没有opt参数,你将有一个与所有你想要的信息的关联数组)
更多信息请访问:http://php.net/manual/fr/function.curl-getinfo.php