Returning header as array using Curl

前端 未结 9 1902
再見小時候
再見小時候 2020-12-01 04:22

I\'m trying to get the response & the response headers from CURL using PHP, specifically for Content-Disposition: attachment; so I can return the filename passed within

相关标签:
9条回答
  • 2020-12-01 04:56

    Fixing issues:

    • Error when content of the header contained ': '(split string)
    • Multiline-headers were not supported
    • Duplicate headers (Set-Cookie) were not supported

    This is my take on the topic ;-)

    list($head, $body)=explode("\r\n\r\n", $content, 2);
    $headers=parseHeaders($head); 
    
    function parseHeaders($text) {
        $headers=array();
    
        foreach (explode("\r\n", $text) as $i => $line) {
            // Special HTTP first line
            if (!$i && preg_match('@^HTTP/(?<protocol>[0-9.]+)\s+(?<code>\d+)(?:\s+(?<message>.*))?$@', $line, $match)) {
                $headers['@status']=$line;
                $headers['@code']=$match['code'];
                $headers['@protocol']=$match['protocol'];
                $headers['@message']=$match['message'];
                continue;
            }
    
            // Multiline header - join with previous
            if ($key && preg_match('/^\s/', $line)) {
                $headers[$key].=' '.trim($line);
                continue;
            }
    
            list ($key, $value) = explode(': ', $line, 2);
            $key=strtolower($key);
            // Append duplicate headers - namely Set-Cookie header
            $headers[$key]=isset($headers[$key]) ? $headers[$key].' ' : $value;
        }
    
        return $headers;
    }
    
    0 讨论(0)
  • 2020-12-01 05:00

    Another my implementation:

    function getHeaders($response){
    
        if (!preg_match_all('/([A-Za-z\-]{1,})\:(.*)\\r/', $response, $matches) 
                || !isset($matches[1], $matches[2])){
            return false;
        }
    
        $headers = [];
    
        foreach ($matches[1] as $index => $key){
            $headers[$key] = $matches[2][$index];
        }
    
        return $headers;
    }
    

    Used in case, which request format is:

    Host: *
    Accept: *
    Content-Length: *
    and etc ...

    0 讨论(0)
  • 2020-12-01 05:06

    C.hill's answer is great but breaks when retrieving multiple cookies. Made the change here

    public function get_headers_from_curl_response($response) { 
        $headers = array(); 
        $header_text = substr($response, 0, strpos($response, "\r\n\r\n")); 
        foreach (explode("\r\n", $header_text) as $i => $line) 
             if ($i === 0) $headers['http_code'] = $line; 
             else { 
                  list ($key, $value) = explode(': ', $line); $headers[$key][] = $value; 
             } 
        return $headers; 
    }
    
    0 讨论(0)
  • 2020-12-01 05:11

    Using the array() form for method callbacks should make the original example work:

    curl_setopt($this->_ch, CURLOPT_HEADERFUNCTION, array($this, 'readHeader'));

    0 讨论(0)
  • 2020-12-01 05:12

    you can do 2 ways

    1. by set curl_setopt($this->_ch, CURLOPT_HEADER, true); header will come out with response message from curl_exec(); you must search keyword 'Content-Disposition:' from response message.

    2. by use this function get_headers($url) right after you call curl_exec(). $url is url called in curl. the return is array of headers. search for 'Content-Disposition' in array to get what you want.

    0 讨论(0)
  • 2020-12-01 05:14

    The anwser from c.hill is great but the code will not handle if the first response is a 301 or 302 - in that case only the first header will be added to the array returned by get_header_from_curl_response().

    I've updated the function to return an array with each of the headers.

    First I use this lines to create a variable with only the header content

    $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
    $header = substr($a, 0, $header_size);
    

    Than I pass $header in to the new get_headers_from_curl_response()-function:

    static function get_headers_from_curl_response($headerContent)
    {
    
        $headers = array();
    
        // Split the string on every "double" new line.
        $arrRequests = explode("\r\n\r\n", $headerContent);
    
        // Loop of response headers. The "count() -1" is to 
        //avoid an empty row for the extra line break before the body of the response.
        for ($index = 0; $index < count($arrRequests) -1; $index++) {
    
            foreach (explode("\r\n", $arrRequests[$index]) as $i => $line)
            {
                if ($i === 0)
                    $headers[$index]['http_code'] = $line;
                else
                {
                    list ($key, $value) = explode(': ', $line);
                    $headers[$index][$key] = $value;
                }
            }
        }
    
        return $headers;
    }
    

    This function will take header like this:

    HTTP/1.1 302 Found
    Cache-Control: no-cache
    Pragma: no-cache
    Content-Type: text/html; charset=utf-8
    Expires: -1
    Location: http://www.website.com/
    Server: Microsoft-IIS/7.5
    X-AspNet-Version: 4.0.30319
    Date: Sun, 08 Sep 2013 10:51:39 GMT
    Connection: close
    Content-Length: 16313
    
    HTTP/1.1 200 OK
    Cache-Control: private
    Content-Type: text/html; charset=utf-8
    Server: Microsoft-IIS/7.5
    X-AspNet-Version: 4.0.30319
    Date: Sun, 08 Sep 2013 10:51:39 GMT
    Connection: close
    Content-Length: 15519
    

    And return an array like this:

    (
        [0] => Array
            (
                [http_code] => HTTP/1.1 302 Found
                [Cache-Control] => no-cache
                [Pragma] => no-cache
                [Content-Type] => text/html; charset=utf-8
                [Expires] => -1
                [Location] => http://www.website.com/
                [Server] => Microsoft-IIS/7.5
                [X-AspNet-Version] => 4.0.30319
                [Date] => Sun, 08 Sep 2013 10:51:39 GMT
                [Connection] => close
                [Content-Length] => 16313
            )
    
        [1] => Array
            (
                [http_code] => HTTP/1.1 200 OK
                [Cache-Control] => private
                [Content-Type] => text/html; charset=utf-8
                [Server] => Microsoft-IIS/7.5
                [X-AspNet-Version] => 4.0.30319
                [Date] => Sun, 08 Sep 2013 10:51:39 GMT
                [Connection] => close
                [Content-Length] => 15519
            )
    
    )
    
    0 讨论(0)
提交回复
热议问题