Can PHP cURL retrieve response headers AND body in a single request?

后端 未结 13 1735
粉色の甜心
粉色の甜心 2020-11-22 03:28

Is there any way to get both headers and body for a cURL request using PHP? I found that this option:

curl_setopt($ch, CURLOPT_HEADER, true);
相关标签:
13条回答
  • 2020-11-22 03:47

    If you specifically want the Content-Type, there's a special cURL option to retrieve it:

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $response = curl_exec($ch);
    $content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
    
    0 讨论(0)
  • 2020-11-22 03:52

    Just in case you can't / don't use CURLOPT_HEADERFUNCTION or other solutions;

    $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));
    }
    
    0 讨论(0)
  • 2020-11-22 03:55

    One solution to this was posted in the PHP documentation comments: http://www.php.net/manual/en/function.curl-exec.php#80442

    Code example:

    $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);
    

    Warning: As noted in the comments below, this may not be reliable when used with proxy servers or when handling certain types of redirects. @Geoffrey's answer may handle these more reliably.

    0 讨论(0)
  • 2020-11-22 03:56

    If you don't really need to use curl;

    $body = file_get_contents('http://example.com');
    var_export($http_response_header);
    var_export($body);
    

    Which outputs

    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>...
    

    See http://php.net/manual/en/reserved.variables.httpresponseheader.php

    0 讨论(0)
  • 2020-11-22 03:58

    Many of the other solutions offered this thread are not doing this correctly.

    • Splitting on \r\n\r\n is not reliable when CURLOPT_FOLLOWLOCATION is on or when the server responds with a 100 code.
    • Not all servers are standards compliant and transmit just a \n for new lines.
    • Detecting the size of the headers via CURLINFO_HEADER_SIZE is also not always reliable, especially when proxies are used or in some of the same redirection scenarios.

    The most correct method is using CURLOPT_HEADERFUNCTION.

    Here is a very clean method of performing this using PHP closures. It also converts all headers to lowercase for consistent handling across servers and HTTP versions.

    This version will retain duplicated headers

    This complies with RFC822 and RFC2616, please do not suggest edits to make use of the mb_ string functions, it is incorrect!

    $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);
    
    0 讨论(0)
  • 2020-11-22 03:58

    is this what are you looking to?

    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
    $response = curl_exec($ch); 
    list($header, $body) = explode("\r\n\r\n", $response, 2);
    
    0 讨论(0)
提交回复
热议问题