Вопрос по php – Возврат заголовка в виде массива с использованием Curl

24

Я пытаюсь получить ответ & amp; заголовки ответа от CURL с использованием PHP, специально для Content-Disposition: attachment; поэтому я могу вернуть имя файла, переданное в заголовке. Похоже, что это не возвращается в curl_getinfo.

Я пытался использовать функцию HeaderFunction для вызова функции для чтения дополнительных заголовков, однако я не могу добавить содержимое в массив.

У кого-нибудь есть идеи, пожалуйста?

Ниже приведена часть моего кода, который представляет собой класс-оболочку Curl:

 ...
 curl_setopt($this->_ch, CURLOPT_URL, $this->_url);
 curl_setopt($this->_ch, CURLOPT_HEADER, false);
 curl_setopt($this->_ch, CURLOPT_POST, 1);
 curl_setopt($this->_ch, CURLOPT_POSTFIELDS, $this->_postData);
 curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, 1);
 curl_setopt($this->_ch, CURLOPT_USERAGENT, $this->_userAgent);
 curl_setopt($this->_ch, CURLOPT_HEADERFUNCTION, 'readHeader');

 $this->_response = curl_exec($this->_ch);
 $info = curl_getinfo($this->_ch);
 ...


 function readHeader($ch, $header)
 {
      array_push($this->_headers, $header);
 }
Я должен добавить, что функция readHeader является частью класса оболочки curl. Используя & quot; $ this- & gt; readHeader & apos; не работает. StuffandBlah
Согласно документам, вашreadHeader Функция должна возвращать количество записанных байтов. Добавлениеreturn strlen($header) должен сделать эту работу marcfrodi

Ваш Ответ

8   ответов
0

array() Форма для обратных вызовов методов должна сделать оригинальный пример работы:

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

1

$headers = [];
// Get the response body as string
$response = curl_exec($curl);
// Get the response headers as string
$headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
// Get the substring of the headers and explode as an array by \r\n
// Each element of the array will be a string `Header-Key: Header-Value`
// Retrieve this two parts with a simple regex `/(.*?): (.*)/`
foreach(explode("\r\n", trim(substr($response, 0, $headerSize))) as $row) {
    if(preg_match('/(.*?): (.*)/', $row, $matches)) {
        $headers[$matches[1]] = $matches[2];
    }
}
-1

http_parse_headers функция.

Оно произошло отPECL но вы найдетеотступления в этой теме.

@ mindplay.dk Вы правы: выход из PECL не делает его стандартом. В любом случае pecl_http помечен как стабильный с версии 1.0.0 в 2006 году, последняя стабильная версия - версия 3.1.0. Я перефразировал свой ответ, чтобы прояснить его.
Возможно, немного вводит в заблуждение, говоря, что это «стандарт». - это не стандартное расширение, например не поставляется с PHP и не имеет официальной сборки Windows. Это также все еще0.x что означает, что он нестабилен. Я бы не зависел от этого до тех пор, пока он не будет помечен как стабильный и предпочтительно официально упакован как стандартное расширение PHP.
28

но код не будет обрабатываться, если первый ответ - 301 или 302 - в этом случае только первый заголовок будет добавлен в массив, возвращенный get_header_from_curl_response ().

Я обновил функцию, чтобы она возвращала массив с каждым из заголовков.

Сначала я использую эти строки для создания переменной только с содержимым заголовка

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

Затем я передаю $ header в новую функцию get_headers_from_curl_response ():

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;
}

Эта функция будет принимать заголовок так:

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

И вернуть массив, как это:

(
    [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

но ломается при получении нескольких файлов cookie. Сделал изменения здесь

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

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;
}

Используется в том случае, если формат запроса:

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

61

curl_setopt($this->_ch, CURLOPT_URL, $this->_url);
curl_setopt($this->_ch, CURLOPT_HEADER, 1);
curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, 1);

$response = curl_exec($this->_ch);
$info = curl_getinfo($this->_ch);

$headers = get_headers_from_curl_response($response);

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;
}
Это делает трюк. Спасибо! StuffandBlah
имена заголовков нечувствительны к регистру, так что, вероятно, лучше использовать $ key в нижнем регистре. Кроме того, несколько заголовков могут иметь одинаковое имя /
-3

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.

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.

Использование get_headers () приведет к ненужной загрузке сервера вторым HTTP-запросом и может дать совершенно другой набор заголовков.

Похожие вопросы