Intereting Posts
PHP-код внутри XML? Как обратиться к public_html корневому файлу, используя include, после того, как вы перейдете к одной файловой директории из public_html Можно ли перенести все глобальные переменные php в локальную область функции? Переведите намерение этого регулярного выражения PHP для многострочных строк в Python / PERL mySQL – установить уровень изоляции с помощью PHP mysqli og: описание 'content' unterminated string literal Удаление всех символов перед определенной строкой PHP – Как объединить массивы в один массив во время цикла? Импортировать CSV-файл непосредственно в базу данных MySQL substr_count не работает с новыми строками? как сделать простое приложение php отправлять электронные письма из кедра кедра герою? Есть ли способ определить, был ли файл excel создан в Windows или Mac с помощью PHPExcel? Необходимо найти широту и долготу почтовых индексов и сохранить в моей базе данных Каков наилучший способ разобрать Paypal NVP в PHP? Функция вызова Codeigniter в контроллере без index.php

Возвращение заголовка в виде массива с помощью Curl

Я пытаюсь получить ответ и заголовки ответов из 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); } 

Здесь это должно сделать это:

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

Андерс c.hill замечательный, но код не обрабатывается, если первый ответ 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 ) ) 

Простой и понятный

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

Использование формы array() для обратных вызовов метода должно привести к тому, что исходный пример будет работать:

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

Еще одна моя реализация:

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

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

Хост: *
Принять: *
Content-Length: *
и так далее …

Вы можете использовать функцию http_parse_headers .

Он исходит из PECL, но вы найдете резервные копии в этой нити SO .

вы можете сделать 2 способа

  1. по набору curl_setopt ($ this -> _ ch, CURLOPT_HEADER, true); заголовок выйдет с ответным сообщением от curl_exec (); вы должны найти ключевое слово «Content-Disposition:» из ответного сообщения.

  2. используя эту функцию get_headers ($ url) сразу после вызова curl_exec (). $ url – url, вызываемый в curl. return – массив заголовков. найдите «Content-Disposition» в массиве, чтобы получить то, что вы хотите.