是否有任何方法来获得头部和主体的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);

其他回答

杰弗里回答的改进:

我不能得到正确的长度头部与$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'))
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);

这就是你想要的吗?

curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
$response = curl_exec($ch); 
list($header, $body) = explode("\r\n\r\n", $response, 2);

只需设置选项:

CURLOPT_HEADER, 0岁 CURLOPT_RETURNTRANSFER, 1

并使用curl_getinfo与CURLINFO_HTTP_CODE(或没有opt参数,你将有一个与所有你想要的信息的关联数组)

更多信息请访问:http://php.net/manual/fr/function.curl-getinfo.php