Czy jest jakiś sposób na uzyskanie zarówno nagłówków, jak i treści dla żądania cURL za pomocą PHP? Odkryłem, że ta opcja:
curl_setopt($ch, CURLOPT_HEADER, true);
zwróci ciało wraz z nagłówkami , ale potem muszę je przeanalizować, aby uzyskać ciało. Czy jest jakiś sposób, aby uzyskać oba w bardziej użyteczny (i bezpieczny) sposób?
Zauważ, że w przypadku „pojedynczego żądania” mam na myśli unikanie wydawania żądania HEAD przed GET / POST.
Odpowiedzi:
Jedno rozwiązanie tego zostało zamieszczone w komentarzach do dokumentacji PHP: http://www.php.net/manual/en/function.curl-exec.php#80442
Przykład kodu:
Ostrzeżenie: jak zauważono w komentarzach poniżej, może to nie być niezawodne, gdy jest używane z serwerami proxy lub podczas obsługi niektórych rodzajów przekierowań. Odpowiedź Geoffreya może obsłużyć je bardziej niezawodnie.
źródło
list($header, $body) = explode("\r\n\r\n", $response, 2)
, ale może to potrwać nieco dłużej, w zależności od wielkości żądania.list($header, $body) = explode("\r\n\r\n", $response, 2)
jako jedynego działającego wariantu100
(Kontynuuj). W przypadku tego nagłówka możesz obejść z poprawnie zdefiniowaną opcją żądania:curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
wyłączając wysyłanie tej odpowiedzi nagłówka. Co do302
tego, nie powinno się to zdarzyć, ponieważ nagłówek 302 jest przekierowany, nie oczekuje treści, jednak wiem, że czasami serwery wysyłają jakieś302
odpowiedzi z odpowiedzią, ale i tak będą ignorowane przez przeglądarki, do tej pory, dlaczego curl powinien sobie z tym poradzić? )CURLOPT_VERBOSE
ma na celu przekazywanie informacji o procesie doSTDERR
(może przeszkadzać w CLI) i dla omawianego problemu jest bezużyteczny.Wiele innych rozwiązań oferowanych w tym wątku nie robi tego poprawnie.
\r\n\r\n
nie jest niezawodne, gdyCURLOPT_FOLLOWLOCATION
jest włączone lub gdy serwer odpowiada kodem 100.\n
dla nowych linii.CURLINFO_HEADER_SIZE
również nie zawsze jest niezawodne, szczególnie gdy używane są serwery proxy lub w niektórych scenariuszach przekierowania.Używana jest najbardziej poprawna metoda
CURLOPT_HEADERFUNCTION
.Oto bardzo czysta metoda wykonywania tego przy użyciu zamknięć PHP. Konwertuje również wszystkie nagłówki na małe litery, aby zapewnić spójną obsługę serwerów i wersji HTTP.
Ta wersja zachowa zduplikowane nagłówki
Jest to zgodne z RFC822 i RFC2616, proszę nie sugerować zmian w celu korzystania z
mb_
funkcji ciągów, jest to niepoprawne!źródło
$headers = [];
ważny jest php?Curl ma wbudowaną opcję tego, o nazwie CURLOPT_HEADERFUNCTION. Wartością tej opcji musi być nazwa funkcji zwrotnej. Curl przekazuje nagłówek (i tylko nagłówek!) Do tej funkcji zwrotnej, linia po linii (więc funkcja będzie wywoływana dla każdej linii nagłówka, zaczynając od góry sekcji nagłówka). Twoja funkcja zwrotna może wtedy z nią zrobić wszystko (i musi zwrócić liczbę bajtów danej linii). Oto sprawdzony działający kod:
Powyższe działa ze wszystkim, różnymi protokołami i serwerami proxy, i nie musisz martwić się o rozmiar nagłówka lub ustawić wiele różnych opcji zwijania.
PS: Aby obsłużyć linie nagłówka za pomocą metody obiektowej, wykonaj następujące czynności:
źródło
czy tego właśnie szukasz?
źródło
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
w komentarzu pod „poprawną” odpowiedzią .Wystarczy ustawić opcje:
CURLOPT_HEADER, 0
CURLOPT_RETURNTRANSFER, 1
i użyj curl_getinfo z CURLINFO_HTTP_CODE (lub bez parametru opt, a będziesz miał tablicę asocjacyjną ze wszystkimi potrzebnymi informacjami)
Więcej na: http://php.net/manual/fr/function.curl-getinfo.php
źródło
curl_getinfo()
.Jeśli chcesz
Content-Type
, jest dostępna specjalna opcja cURL:źródło
Działa z
HTTP/1.1 100 Continue
innymi nagłówkami.Jeśli potrzebujesz pracy z błędnymi serwerami, które wysyłają tylko LF zamiast CRLF jako podziały linii, możesz użyć
preg_split
w następujący sposób:źródło
$parts = explode("\r\n\r\nHTTP/", $response);
trzeci parametr parametru Explode nie powinien mieć wartości 2?HTTP/1.1 100 Continue
może pojawić się wiele razy.HTTP/1.1 100 Continue
może pojawić się wiele razy. Wyświetlany jest przypadek, jeśli pojawia się tylko jeden raz, ale w powszechnym przypadku jest niepoprawny. Na przykładHTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK...\r\n\r\n...
jego kod nie działa poprawnieMoja droga jest taka
W razie potrzeby zastosuj pętlę for i usuń limit wybuchu.
źródło
Oto mój wkład w debatę ... Zwraca jedną tablicę z oddzielonymi danymi i wymienionymi nagłówkami. Działa to na podstawie tego, że CURL zwróci dane fragmentu nagłówków [pusta linia]
źródło
Problem z wieloma odpowiedziami tutaj
"\r\n\r\n"
może polegać na tym, że mogą pojawić się w treści html, więc nie możesz być pewien, że poprawnie dzielisz nagłówki.Wydaje się, że jedynym sposobem na przechowywanie nagłówków osobno za pomocą jednego wywołania
curl_exec
jest użycie wywołania zwrotnego, jak sugerowano powyżej w https://stackoverflow.com/a/25118032/3326494Następnie, aby (niezawodnie) uzyskać tylko treść żądania, musisz przekazać wartość
Content-Length
nagłówkasubstr()
jako ujemną wartość początkową.źródło
list($head, $body) = explode("\r\n\r\n", $response, 2);
jednak CURL już to robi, jeśli używaszcurl_setopt($ch, CURLOPT_HEADERFUNCTION, $myFunction);
Na wypadek, gdybyś nie mógł / nie używał
CURLOPT_HEADERFUNCTION
lub innych rozwiązań;źródło
Zwróć nagłówki odpowiedzi z parametrem referencyjnym:
źródło
$rtn=explode("\r\n\r\nHTTP/", $rtn, 2);
rację? Czy trzeci parametr rozstrzelenia nie powinien zostać usunięty?explode("\r\n\r\n", $parts, 2);
więc oba mają rację.Jeśli tak naprawdę nie musisz używać curl;
Które wyjścia
Zobacz http://php.net/manual/en/reserved.variables.httpresponseheader.php
źródło