Есть ли способ получить заголовки и тело для запроса cURL, используя PHP? Я обнаружил, что этот вариант:
curl_setopt($ch, CURLOPT_HEADER, true);
собирается вернуть тело плюс заголовки , но затем мне нужно разобрать его, чтобы получить тело. Есть ли способ получить как более удобный (и безопасный) способ?
Обратите внимание, что для «одного запроса» я имею в виду избегать выдачи запроса HEAD до GET / POST.
Ответы:
Одно из решений было опубликовано в комментариях к документации PHP: http://www.php.net/manual/en/function.curl-exec.php#80442
Пример кода:
Предупреждение: как отмечено в комментариях ниже, это может быть ненадежно при использовании с прокси-серверами или при обработке определенных типов перенаправлений. Ответ @ Джеффри может обработать их более надежно.
источник
list($header, $body) = explode("\r\n\r\n", $response, 2)
, но это может занять немного больше времени, в зависимости от размера вашего запроса.list($header, $body) = explode("\r\n\r\n", $response, 2)
100
(Продолжить). Для этого заголовка вы можете использовать правильную опцию запроса:curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
отключить отправку ответа этого заголовка. Что касается302
этого, этого не должно происходить, потому что заголовок 302 - это перенаправление, он не ожидает тела, однако я знаю, что иногда серверы отправляют какое-то тело с302
ответом, но браузеры все равно будут игнорироваться, почему же curl должен справиться с этим? )CURLOPT_VERBOSE
предназначен для вывода информации о процессеSTDERR
(может беспокоить в CLI) и для обсуждаемой проблемы бесполезно.Многие из других решений , предлагаемых эта нить не делают это правильно.
\r\n\r\n
не надежно, когдаCURLOPT_FOLLOWLOCATION
включено, или когда сервер отвечает кодом 100.\n
для новых линий.CURLINFO_HEADER_SIZE
также не всегда надежно, особенно когда используются прокси или в некоторых из тех же сценариев перенаправления.Самый правильный метод использует
CURLOPT_HEADERFUNCTION
.Вот очень чистый метод выполнения этого с использованием замыканий PHP. Он также преобразует все заголовки в нижний регистр для согласованной обработки между серверами и версиями HTTP.
Эта версия сохранит дублированные заголовки
Это соответствует RFC822 и RFC2616, пожалуйста, не предлагайте правки для использования
mb_
строковых функций, это неверно!источник
$headers = [];
Действительный php?У Curl есть встроенная опция для этого, которая называется CURLOPT_HEADERFUNCTION. Значение этой опции должно быть именем функции обратного вызова. Curl будет передавать заголовок (и только заголовок!) Этой функции обратного вызова, строка за строкой (поэтому функция будет вызываться для каждой строки заголовка, начиная с верхней части раздела заголовка). Ваша функция обратного вызова затем может делать с ней что угодно (и должна возвращать количество байтов в данной строке). Вот проверенный рабочий код:
Вышесказанное работает со всем, с разными протоколами и прокси-серверами, и вам не нужно беспокоиться о размере заголовка или устанавливать множество различных параметров curl.
PS: Чтобы обработать строки заголовка с помощью метода объекта, сделайте это:
источник
это то, что вы ищете?
источник
A server that does not understand or is unable to comply with any of the expectation values in the Expect field of a request MUST respond with appropriate error status. The server MUST respond with a 417 (Expectation Failed) status if any of the expectations cannot be met or, if there are other problems with the request, some other 4xx status.
100
в комментарии под "правильным" ответом .Просто установите параметры:
CURLOPT_HEADER, 0
CURLOPT_RETURNTRANSFER, 1
и используйте curl_getinfo с CURLINFO_HTTP_CODE (или без параметра opt, и у вас будет ассоциативный массив со всей необходимой информацией)
Больше на: http://php.net/manual/fr/function.curl-getinfo.php
источник
curl_getinfo()
.Если вы конкретно хотите
Content-Type
, есть специальная опция cURL для ее получения:источник
Работает с
HTTP/1.1 100 Continue
другими заголовками.Если вам нужно работать с ошибочными серверами, которые отправляют только LF вместо CRLF в качестве разрывов строк, вы можете использовать
preg_split
следующее:источник
$parts = explode("\r\n\r\nHTTP/", $response);
иметь 3-й параметр для взрыва как 2?HTTP/1.1 100 Continue
может появиться много раз.HTTP/1.1 100 Continue
может появиться много раз. Он рассматривает случай, если он появляется только один раз, но в общем случае он неверен. Например,HTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK...\r\n\r\n...
его код не работает должным образомМой путь
При необходимости примените цикл for и удалите предел разнесения.
источник
Вот мой вклад в дебаты ... Это возвращает один массив с разделенными данными и заголовками в списке. Это работает на основе того, что CURL будет возвращать данные блока заголовков [пустая строка]
источник
Проблема многих ответов здесь заключается в том, что они
"\r\n\r\n"
могут законно появляться в теле html, поэтому вы не можете быть уверены, что правильно разбиваете заголовки.Кажется, что единственный способ хранить заголовки отдельно с одним вызовом
curl_exec
- это использовать обратный вызов, как это было предложено выше в https://stackoverflow.com/a/25118032/3326494А затем, чтобы (надежно) получить только тело запроса, вам нужно передать значение
Content-Length
заголовкаsubstr()
как отрицательное начальное значение.источник
list($head, $body) = explode("\r\n\r\n", $response, 2);
, однако CURL уже делает это для вас , если вы используетеcurl_setopt($ch, CURLOPT_HEADERFUNCTION, $myFunction);
На тот случай, если вы не можете / не используете
CURLOPT_HEADERFUNCTION
или другие решения;источник
Вернуть заголовки ответа со ссылочным параметром:
источник
$rtn=explode("\r\n\r\nHTTP/", $rtn, 2);
это правильно? Не следует ли удалить 3-й параметр разнесения?explode("\r\n\r\n", $parts, 2);
так что оба правы.Если вам не нужно использовать curl;
Какие выводы
См. Http://php.net/manual/en/reserved.variables.httpresponseheader.php
источник