Gibt es eine Möglichkeit, sowohl Header als auch Body für eine cURL-Anfrage mit PHP abzurufen? Ich fand, dass diese Option:
curl_setopt($ch, CURLOPT_HEADER, true);
wird den Körper plus Überschriften zurückgeben , aber dann muss ich ihn analysieren, um den Körper zu erhalten. Gibt es eine Möglichkeit, beides benutzerfreundlicher (und sicherer) zu machen?
Beachten Sie, dass ich für "Einzelanforderung" die Ausgabe einer HEAD-Anforderung vor GET / POST vermeiden möchte.
Antworten:
Eine Lösung hierfür wurde in den Kommentaren zur PHP-Dokumentation veröffentlicht: http://www.php.net/manual/en/function.curl-exec.php#80442
Codebeispiel:
Warnung: Wie in den Kommentaren unten angegeben, ist dies möglicherweise nicht zuverlässig, wenn es mit Proxyservern verwendet wird oder wenn bestimmte Arten von Weiterleitungen verarbeitet werden. @ Geoffrey Antwort kann diese zuverlässiger behandeln.
quelle
list($header, $body) = explode("\r\n\r\n", $response, 2)
, dies kann jedoch je nach Anforderungsgröße etwas länger dauern.list($header, $body) = explode("\r\n\r\n", $response, 2)
als einzige funktionierende Variante verwenden100
(Weiter). Für diesen Header können Sie die Anforderungsoption korrekt definieren:curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
Deaktivieren Sie das Senden dieser Header-Antwort.302
Dies sollte nicht passieren, da der 302-Header umgeleitet wird und keinen Body erwartet. Wie ich jedoch weiß, senden Server manchmal einen Body mit302
Antwort, aber er wird von den Browsern bisher trotzdem ignoriert. Warum sollte Curl damit umgehen? )CURLOPT_VERBOSE
ist dazu gedacht, Prozessinformationen anSTDERR
(kann in der CLI stören) auszugeben und ist für das diskutierte Problem nutzlos.Viele der anderen in diesem Thread angebotenen Lösungen machen dies nicht richtig.
\r\n\r\n
ist nicht zuverlässig, wenn es eingeschaltetCURLOPT_FOLLOWLOCATION
ist oder wenn der Server mit einem 100-Code antwortet.\n
für neue Leitungen.CURLINFO_HEADER_SIZE
ist auch nicht immer zuverlässig, insbesondere wenn Proxys verwendet werden oder in einigen der gleichen Umleitungsszenarien.Die korrekteste Methode ist die Verwendung
CURLOPT_HEADERFUNCTION
.Hier ist eine sehr saubere Methode, um dies mit PHP-Closures durchzuführen. Außerdem werden alle Header in Kleinbuchstaben konvertiert, um eine konsistente Behandlung zwischen Servern und HTTP-Versionen zu gewährleisten.
Diese Version behält doppelte Header bei
Dies entspricht RFC822 und RFC2616. Bitte schlagen Sie keine Änderungen vor, um die
mb_
Zeichenfolgenfunktionen nutzen zu können. Es ist falsch!quelle
$headers = [];
gültiges PHP?Curl verfügt hierfür über eine integrierte Option namens CURLOPT_HEADERFUNCTION. Der Wert dieser Option muss der Name einer Rückruffunktion sein. Curl übergibt den Header (und nur den Header!) Zeile für Zeile an diese Rückruffunktion (die Funktion wird also für jede Headerzeile beginnend am oberen Rand des Header-Abschnitts aufgerufen). Ihre Rückruffunktion kann dann alles damit machen (und muss die Anzahl der Bytes der angegebenen Zeile zurückgeben). Hier ist ein getesteter Arbeitscode:
Das Obige funktioniert mit allem, auch mit verschiedenen Protokollen und Proxys, und Sie müssen sich keine Gedanken über die Headergröße machen oder viele verschiedene Curl-Optionen festlegen.
PS: Um die Kopfzeilen mit einer Objektmethode zu behandeln, gehen Sie folgendermaßen vor:
quelle
ist es das, wonach du suchst?
quelle
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
im Kommentar unter "richtige" Antwort .Einfach Optionen einstellen:
CURLOPT_HEADER, 0
CURLOPT_RETURNTRANSFER, 1
und verwenden Sie curl_getinfo mit CURLINFO_HTTP_CODE (oder ohne opt param und Sie haben ein assoziatives Array mit allen gewünschten Informationen)
Mehr unter: http://php.net/manual/fr/function.curl-getinfo.php
quelle
curl_getinfo()
.Wenn Sie das speziell möchten
Content-Type
, gibt es eine spezielle cURL-Option, um es abzurufen:quelle
Funktioniert mit
HTTP/1.1 100 Continue
vor anderen Headern.Wenn Sie mit fehlerhaften Servern arbeiten müssen, die nur LF anstelle von CRLF als Zeilenumbrüche senden, können Sie
preg_split
Folgendes verwenden:quelle
$parts = explode("\r\n\r\nHTTP/", $response);
3. Parameter für die Explosion nicht 2 sein?HTTP/1.1 100 Continue
kann viele Male auftreten.HTTP/1.1 100 Continue
kann viele Male auftreten. Er sieht den Fall an, wenn er nur einmal erscheint, aber im allgemeinen Fall ist er falsch. Zum Beispiel fürHTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK...\r\n\r\n...
seinen Code nicht richtig funktionierenMein Weg ist
Wenden Sie bei Bedarf eine for-Schleife an und entfernen Sie die Explosionsgrenze.
quelle
Hier ist mein Beitrag zur Debatte ... Dies gibt ein einzelnes Array mit getrennten Daten und aufgelisteten Headern zurück. Dies funktioniert auf der Grundlage, dass CURL einen Header-Chunk [leere Zeile] zurückgibt
quelle
Das Problem mit vielen Antworten hier ist, dass
"\r\n\r\n"
es legitimerweise im HTML-Text erscheinen kann, sodass Sie nicht sicher sein können, ob Sie die Header korrekt aufteilen.Es scheint, dass die einzige Möglichkeit, Header mit einem Aufruf von separat zu speichern, darin
curl_exec
besteht, einen Rückruf zu verwenden, wie oben unter https://stackoverflow.com/a/25118032/3326494 vorgeschlagenUnd um dann (zuverlässig) nur den Hauptteil der Anforderung zu erhalten, müssten Sie den Wert des
Content-Length
Headerssubstr()
als negativen Startwert übergeben.quelle
list($head, $body) = explode("\r\n\r\n", $response, 2);
CURL erledigt dies jedoch bereits für Sie, wenn Siecurl_setopt($ch, CURLOPT_HEADERFUNCTION, $myFunction);
Nur für den Fall, dass Sie keine
CURLOPT_HEADERFUNCTION
anderen Lösungen verwenden können / wollen ;quelle
Antwortheader mit einem Referenzparameter zurückgeben:
quelle
$rtn=explode("\r\n\r\nHTTP/", $rtn, 2);
es richtig ist? Sollte der dritte Explosionsparameter nicht entfernt werden?explode("\r\n\r\n", $parts, 2);
also sind beide richtig.Wenn Sie Curl nicht wirklich verwenden müssen;
Welche Ausgänge
Siehe http://php.net/manual/en/reserved.variables.httpresponseheader.php
quelle