Ich wurde angewiesen, die Methode php://input
anstelle der $_POST
Interaktion mit Ajax-Anforderungen von JQuery zu verwenden. Was ich nicht verstehe, sind die Vorteile dieser Verwendung gegenüber der globalen Methode von $_POST
oder $_GET
.
243
Antworten:
Der Grund ist, dass
php://input
alle Rohdaten nach den HTTP-Headern der Anfrage zurückgegeben werden, unabhängig vom Inhaltstyp.Die PHP - Superglobal
$_POST
, nur auf vermeintliche Wrap Daten , die entwederapplication/x-www-form-urlencoded
(Standardinhaltstyp für einfache Formularbeiträge) odermultipart/form-data
(meistens für Datei-Uploads verwendet)Dies liegt daran, dass dies die einzigen Inhaltstypen sind , die von Benutzeragenten unterstützt werden müssen . Daher erwarten der Server und PHP traditionell keinen anderen Inhaltstyp (was nicht bedeutet, dass sie dies nicht können).
Wenn Sie also einfach einen guten alten HTML-Code veröffentlichen
form
, sieht die Anfrage ungefähr so aus:Wenn Sie jedoch häufig mit Ajax arbeiten, umfasst dieses Probaby auch den Austausch komplexerer Daten mit Typen (Zeichenfolge, Int, Bool) und Strukturen (Arrays, Objekte). In den meisten Fällen ist JSON daher die beste Wahl. Eine Anfrage mit einer JSON-Nutzlast würde jedoch ungefähr so aussehen:
Der Inhalt wäre jetzt
application/json
(oder zumindest keiner der oben genannten), so dass der PHP-$_POST
Wrapper (noch) nicht weiß, wie er damit umgehen soll.Die Daten sind noch vorhanden, Sie können einfach nicht über den Wrapper darauf zugreifen. Sie müssen es also selbst im Rohformat mit abrufen
file_get_contents('php://input')
( solange es nichtmultipart/form-data
-codiert ist ).Auf diese Weise können Sie auch auf XML-Daten oder andere nicht standardmäßige Inhaltstypen zugreifen.
quelle
application/json
als gültige Datenquelle für das$_POST
Array zu erkennen. Und es gibt sogar veröffentlichte Anfragen für speziell diese Unterstützung.php://input
kann Ihnen die Rohbytes der Daten geben. Dies ist nützlich, wenn die POST-Daten eine JSON-codierte Struktur sind, was häufig bei einer AJAX-POST-Anforderung der Fall ist.Hier ist eine Funktion, um genau das zu tun:
Das
$_POST
Array ist nützlicher, wenn Sie Schlüsselwertdaten aus einem Formular verarbeiten, das von einem herkömmlichen POST gesendet wird. Dies funktioniert normalerweise nur, wenn die POST-Daten in einem erkannten Format vorliegenapplication/x-www-form-urlencoded
( Einzelheiten finden Sie unter http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4 ).quelle
true
als zweiten Parameter an übergebenjson_decode
, wird ein assoziatives Array zurückgegeben.Wenn die Postdaten fehlerhaft sind, enthält $ _POST nichts. Die Eingabe von php: // enthält jedoch die fehlerhafte Zeichenfolge.
Zum Beispiel gibt es einige Ajax-Anwendungen, die keine korrekte Post-Key-Value-Sequenz zum Hochladen einer Datei bilden und einfach die gesamte Datei als Post-Daten ohne Variablennamen oder ähnliches ausgeben. $ _POST ist leer, $ _FILES ist ebenfalls leer und die Eingabe von php: // enthält eine genaue Datei, die als Zeichenfolge geschrieben ist.
quelle
Erstens eine grundlegende Wahrheit über PHP.
PHP wurde nicht entwickelt, um Ihnen explizit eine reine REST-ähnliche Schnittstelle (GET, POST, PUT, PATCH, DELETE) für die Verarbeitung von HTTP-Anforderungen zu geben .
Allerdings ist der
$_POST
,$_GET
und$_FILES
superglobals und die Funktionfilter_input_array()
ist sehr nützlich für die durchschnittliche Person / Laien Bedürfnisse.Der versteckte Vorteil Nummer eins von
$_POST
(und$_GET
) ist, dass Ihre Eingabedaten von PHP automatisch urldecodiert werden . Sie denken nicht einmal daran, dies tun zu müssen, insbesondere bei Abfragezeichenfolgenparametern innerhalb einer Standard-GET-Anforderung.Dann lernst du jedoch mehr ...
Wenn Sie jedoch Ihre Programmierkenntnisse erweitern und das JavaScript-
XmlHttpRequest
Objekt (für einige jQuery) verwenden möchten , werden Sie feststellen, dass dieses Schema Einschränkungen aufweist.$_POST
beschränkt Sie auf die Verwendung von zwei Medientypen im HTTP-Content-Type
Header:application/x-www-form-urlencoded
, undmultipart/form-data
Wenn Sie also Datenwerte an PHP auf dem Server senden und diese im
$_POST
Superglobal anzeigen lassen möchten , müssen Sie sie auf der Clientseite urlencodieren und diese Daten als Schlüssel / Wert-Paare senden - ein unpraktischer Schritt für Anfänger (insbesondere, wenn Sie herausfinden möchten, ob verschiedene Teile der URL unterschiedliche Formen der Urlencodierung erfordern: normal, roh usw.).Für alle jQuery-Benutzer
$.ajax()
konvertiert die Methode Ihren JSON in URL-codierte Schlüssel / Wert-Paare, bevor sie an den Server übertragen werden. Sie können dieses Verhalten durch Festlegen überschreibenprocessData: false
. Lesen Sie einfach die Dokumentation zu $ .ajax () und vergessen Sie nicht, den richtigen Medientyp im Content-Type-Header zu senden.URL-Codierung? Was zum Teufel!!!???
Wenn Sie normale, synchrone (wenn die gesamte Seite neu gezeichnet wird) HTTP-Anforderungen mit einem HTML-Formular ausführen, codiert der Benutzeragent (Webbrowser) normalerweise Ihre Formulardaten für Sie. Wenn Sie mit dem
XmlHttpRequest
Objekt asynchrone HTTP-Anforderungen ausführen möchten, müssen Sie eine urlencodierte Zeichenfolge erstellen und diese senden. möchten, wenn diese Daten im$_POST
Superglobal angezeigt werden sollen .Wie sind Sie mit JavaScript in Kontakt? :-)
Das Konvertieren von einem JavaScript-Array oder -Objekt in eine urlencodierte Zeichenfolge stört viele Entwickler (selbst bei neuen APIs wie Formulardaten ). Sie würden viel lieber nur JSON senden können, und das wäre es auch effizienter für den Client-Code, dies zu tun.
Denken Sie daran (zwinker, zwinker), dass der durchschnittliche Webentwickler nicht lernt, das zu verwenden
XmlHttpRequest
Objekt, globale Funktionen, Zeichenfolgenfunktionen, Arrayfunktionen und reguläre Ausdrücke wie Sie und ich direkt ;-). Urlencodierung ist für sie ein Albtraum. ;-);PHP, was gibt es?
Das Fehlen einer intuitiven XML- und JSON-Verarbeitung in PHP macht viele Leute aus. Sie würden denken, dass es jetzt Teil von PHP sein würde (seufz).
So viele Medientypen (MIME-Typen in der Vergangenheit)
XML, JSON und YAML verfügen alle über Medientypen, die in einen HTTP-
Content-Type
Header eingefügt werden können.Schauen Sie, wie viele Medientypen (früher MIME-Typen) von IANA definiert wurden.
Schauen Sie, wie viele HTTP-Header es gibt.
php: // Eingabe oder Pleite
Verwendung der
php://input
Stream können Sie die Abstraktionsstufe für Babysitting / Handhaltung umgehen, die PHP der Welt aufgezwungen hat. :-) Mit großer Macht kommt große Verantwortung!Bevor Sie sich mit Datenwerten befassen, die durch sie gestreamt werden
php://input
, sollten / müssen Sie einige Dinge tun.Was ist mit der Zeichenkodierung?
AH, HA! Ja, Sie möchten möglicherweise, dass der an Ihre Anwendung gesendete Datenstrom UTF-8-codiert wird. Wie können Sie jedoch feststellen, ob dies der Fall ist oder nicht?
Zwei kritische Probleme.
php://input
.Versuchen Sie, Stream-Daten zu verarbeiten, ohne zu wissen, wie viel zuerst vorhanden ist? Das ist eine schreckliche Idee . Sie können sich nicht ausschließlich auf den HTTP-
Content-Length
Header verlassen, um eine Anleitung zur Größe der gestreamten Eingabe zu erhalten, da diese gefälscht werden kann.Sie benötigen eine:
Versuchen Sie, Stream-Daten in UTF-8 zu konvertieren, ohne die aktuelle Codierung des Streams zu kennen? Wie? Der iconv-Stream-Filter ( Beispiel für einen iconv-Stream-Filter ) scheint eine Start- und Endcodierung wie diese zu wollen.
Wenn Sie gewissenhaft sind, benötigen Sie:
( Update :
'convert.iconv.UTF-8/UTF-8'
Erzwingt alles auf UTF-8, aber Sie müssen immer noch Zeichen berücksichtigen, die die iconv-Bibliothek möglicherweise nicht übersetzen kann. Mit anderen Worten, Sie müssen festlegen, welche Aktion ausgeführt werden soll, wenn ein Zeichen nicht übersetzt werden kann : 1) Fügen Sie ein Dummy-Zeichen ein, 2) Fail / Throw und Exception).Sie können sich nicht ausschließlich auf den HTTP-
Content-Encoding
Header verlassen, da dies möglicherweise auf eine Komprimierung wie im Folgenden hinweist. Dies ist nicht das, woraus Sie eine Entscheidung in Bezug auf iconv treffen möchten.Daher könnten die allgemeinen Schritte sein ...
Teil I: HTTP-Anfrage im Zusammenhang
Teil II: Stream-Daten
Teil III: Datentypbezogen
(Denken Sie daran, dass die Daten immer noch eine URL-codierte Zeichenfolge sein können, die Sie dann analysieren und URL-dekodieren müssen.)
Teil IV: Datenwertbezogen
Eingabedaten filtern.
Eingabedaten validieren.
Verstehst du jetzt?
Das
$_POST
Superglobale ist zusammen mit den php.ini-Einstellungen für Eingabegrenzen für den Laien einfacher. Der Umgang mit der Zeichenkodierung ist jedoch bei der Verwendung von Streams viel intuitiver und effizienter, da keine Superglobalen (oder Arrays im Allgemeinen) durchlaufen werden müssen, um die Eingabewerte auf die richtige Kodierung zu überprüfen.quelle
Also habe ich eine Funktion geschrieben, die die POST-Daten aus dem php: // Eingabestream abruft .
Die Herausforderung bestand darin, auf die Anforderungsmethode PUT, DELETE OR PATCH umzuschalten und trotzdem die Post-Daten zu erhalten, die mit dieser Anforderung gesendet wurden.
Ich teile dies vielleicht für jemanden mit einer ähnlichen Herausforderung. Die folgende Funktion ist das, was ich mir ausgedacht habe und sie funktioniert. Ich hoffe, es hilft!
quelle
Einfaches Beispiel für die Verwendung
quelle