Existe alguma maneira de obter cabeçalhos e corpo para uma solicitação cURL usando PHP? Eu achei que esta opção:
curl_setopt($ch, CURLOPT_HEADER, true);
vai retornar o corpo mais os cabeçalhos , mas preciso analisá-lo para obter o corpo. Existe alguma maneira de obter os dois de uma maneira mais utilizável (e segura)?
Observe que, para "solicitação única", evito emitir uma solicitação HEAD antes do GET / POST.
Respostas:
Uma solução para isso foi publicada nos comentários da documentação do PHP: http://www.php.net/manual/en/function.curl-exec.php#80442
Exemplo de código:
Aviso: Conforme observado nos comentários abaixo, isso pode não ser confiável quando usado com servidores proxy ou ao lidar com certos tipos de redirecionamentos. A resposta de @ Geoffrey pode lidar com isso de maneira mais confiável.
fonte
list($header, $body) = explode("\r\n\r\n", $response, 2)
, mas isso pode demorar um pouco mais, dependendo do tamanho da sua solicitação.list($header, $body) = explode("\r\n\r\n", $response, 2)
como única variante trabalhando100
(Continuar). Para este cabeçalho, você pode definir a opção de solicitação corretamente:curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
desativando o envio desta resposta de cabeçalho. Quanto a302
isso, isso não deve acontecer, porque o cabeçalho 302 é redirecionado, ele não espera um corpo, por mais que eu saiba, às vezes os servidores enviam algum corpo com302
resposta, mas ele será ignorado pelos navegadores, até agora, por que o curl deve lidar com isso? )CURLOPT_VERBOSE
destina-se a enviar informações de processo paraSTDERR
(pode incomodar na CLI) e, para o problema discutido, é inútil.Muitas das outras soluções oferecidas nesse segmento não estão fazendo isso corretamente.
\r\n\r\n
não é confiável quandoCURLOPT_FOLLOWLOCATION
está ativada ou quando o servidor responde com um código 100.\n
para novas linhas.CURLINFO_HEADER_SIZE
também nem sempre é confiável, especialmente quando proxies são usados ou em alguns dos mesmos cenários de redirecionamento.O método mais correto está usando
CURLOPT_HEADERFUNCTION
.Aqui está um método muito limpo de executar isso usando fechamentos PHP. Ele também converte todos os cabeçalhos em minúsculas para manipulação consistente entre servidores e versões HTTP.
Esta versão manterá cabeçalhos duplicados
Está em conformidade com RFC822 e RFC2616, por favor não sugerir edições para fazer uso das
mb_
funções de string, pois está incorreto!fonte
$headers = [];
php é válido?O Curl possui uma opção integrada para isso, chamada CURLOPT_HEADERFUNCTION. O valor dessa opção deve ser o nome de uma função de retorno de chamada. A ondulação passará o cabeçalho (e apenas o cabeçalho!) Para essa função de retorno de chamada, linha por linha (para que a função seja chamada para cada linha de cabeçalho, começando na parte superior da seção do cabeçalho). Sua função de retorno de chamada pode fazer qualquer coisa com ela (e deve retornar o número de bytes da linha especificada). Aqui está um código de trabalho testado:
O acima funciona com tudo, protocolos e proxies diferentes também, e você não precisa se preocupar com o tamanho do cabeçalho ou definir muitas opções de ondulação diferentes.
PS: Para manipular as linhas de cabeçalho com um método de objeto, faça o seguinte:
fonte
é isso que você está procurando?
fonte
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
no comentário em resposta "correta" .Basta definir opções:
CURLOPT_HEADER, 0
CURLOPT_RETURNTRANSFER, 1
e use curl_getinfo com CURLINFO_HTTP_CODE (ou nenhum parâmetro de opção e você terá um array associativo com todas as informações que desejar)
Mais em: http://php.net/manual/fr/function.curl-getinfo.php
fonte
curl_getinfo()
.Se você deseja especificamente
Content-Type
, há uma opção especial de cURL para recuperá-lo:fonte
Funciona com
HTTP/1.1 100 Continue
antes de outros cabeçalhos.Se você precisar trabalhar com servidores com bugs, que enviam apenas LF em vez de CRLF como quebras de linha, você pode usar
preg_split
o seguinte:fonte
$parts = explode("\r\n\r\nHTTP/", $response);
ter o terceiro parâmetro para explodir como 2?HTTP/1.1 100 Continue
pode aparecer muitas vezes.HTTP/1.1 100 Continue
pode aparecer muitas vezes. Ele vê o caso se aparecer apenas uma vez, mas está errado no caso comum. Por exemplo, paraHTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK...\r\n\r\n...
o seu código não funcionam corretamenteMeu jeito é
Se necessário, aplique um loop for e remova o limite de explosão.
fonte
Aqui está minha contribuição para o debate ... Isso retorna uma única matriz com os dados separados e os cabeçalhos listados. Isso funciona com base no fato de que CURL retornará dados de um pedaço de cabeçalho [linha em branco]
fonte
O problema com muitas respostas aqui é que
"\r\n\r\n"
elas podem aparecer legitimamente no corpo do html; portanto, você não pode ter certeza de que está dividindo os cabeçalhos corretamente.Parece que a única maneira de armazenar cabeçalhos separadamente com uma chamada
curl_exec
é usar um retorno de chamada, conforme sugerido acima em https://stackoverflow.com/a/25118032/3326494E, para (de maneira confiável) obter apenas o corpo da solicitação, você precisará passar o valor do
Content-Length
cabeçalho parasubstr()
um valor inicial negativo.fonte
list($head, $body) = explode("\r\n\r\n", $response, 2);
, no entanto CURL já faz isso para você se você usarcurl_setopt($ch, CURLOPT_HEADERFUNCTION, $myFunction);
Caso você não possa / não use
CURLOPT_HEADERFUNCTION
ou outras soluções;fonte
Retorne os cabeçalhos de resposta com um parâmetro de referência:
fonte
$rtn=explode("\r\n\r\nHTTP/", $rtn, 2);
está correto? O terceiro parâmetro de explosão não deve ser removido?explode("\r\n\r\n", $parts, 2);
portanto, ambos estão certos.Se você realmente não precisa usar curl;
Quais saídas
Veja http://php.net/manual/en/reserved.variables.httpresponseheader.php
fonte