Wenn ich eine URL mit einer Variablen erstellen möchte, habe ich zwei Möglichkeiten, die Zeichenfolge zu codieren. urlencode()
und rawurlencode()
.
Was genau sind die Unterschiede und welche werden bevorzugt?
php
urlencode
url-encoding
Gary Willoughby
quelle
quelle
rawurlencode
. Sie werden selten auf ein System stoßen, das erstickt, wenn Leerzeichen codiert werden%20
, während Systeme, die an Leerzeichen verschlüsselt+
sind, häufiger als verschlüsselt sind.Antworten:
Es wird von Ihrem Zweck abhängen. Wenn die Interoperabilität mit anderen Systemen wichtig ist, scheint Rawurlencode der richtige Weg zu sein. Die einzige Ausnahme bilden Legacy-Systeme, bei denen erwartet wird, dass die Abfragezeichenfolge dem Formularcodierungsstil von Leerzeichen folgt, die als + anstelle von% 20 codiert sind (in diesem Fall benötigen Sie Urlencode).
rawurlencode folgt RFC 1738 vor PHP 5.3.0 und danach RFC 3986 (siehe http://us2.php.net/manual/en/function.rawurlencode.php )
Hinweis zu RFC 3986 vs 1738. Rawurlencode vor PHP 5.3 codierte das Tilde-Zeichen (
~
) gemäß RFC 1738. Ab PHP 5.3 folgt Rawurlencode jedoch RFC 3986, für das keine Tilde-Zeichen codiert werden müssen.urlencode codiert Leerzeichen als Pluszeichen (nicht wie
%20
im rawurlencode) (siehe http://us2.php.net/manual/en/function.urlencode.php )Dies entspricht der Definition für application / x-www-form-urlencoded in RFC 1866 .
Zusätzliche Lektüre:
Möglicherweise möchten Sie die Diskussion auch unter http://bytes.com/groups/php/5624-urlencode-vs-rawurlencode sehen .
Auch RFC 2396 ist einen Blick wert. RFC 2396 definiert eine gültige URI-Syntax. Der Hauptteil, an dem wir interessiert sind, stammt aus 3.4 Query Component:
Wie Sie sehen können,
+
ist das ein reserviertes Zeichen in der Abfragezeichenfolge und müsste daher gemäß RFC 3986 (wie in rawurlencode) codiert werden.quelle
Der Beweis ist im Quellcode von PHP.
Ich werde Sie durch einen kurzen Prozess führen, wie Sie diese Art von Dingen in Zukunft jederzeit selbst herausfinden können. Denken Sie daran, es wird eine Menge C-Quellcode geben, den Sie überfliegen können (ich erkläre es). Wenn Sie etwas C auffrischen möchten, ist unser SO-Wiki ein guter Anfang .
Laden Sie die Quelle herunter (oder verwenden Sie http://lxr.php.net/, um sie online zu durchsuchen), durchsuchen Sie alle Dateien nach dem Funktionsnamen. Sie finden Folgendes:
PHP 5.3.6 (letzter zum Zeitpunkt des Schreibens) beschreibt die beiden Funktionen in ihrem nativen C - Code in der Datei url.c .
RawUrlEncode ()
UrlEncode ()
Okay, was ist hier anders?
Beide rufen im Wesentlichen zwei verschiedene interne Funktionen auf: php_raw_url_encode und php_url_encode
Suchen Sie also nach diesen Funktionen!
Schauen wir uns php_raw_url_encode an
Und natürlich php_url_encode:
Ein schnell bisschen Wissen , bevor ich vorwärts zu bewegen, EBCDIC ist ein weiterer Zeichensatz , ähnlich wie ASCII, aber insgesamt Wettbewerber. PHP versucht mit beiden umzugehen. Aber im Grunde bedeutet dies, dass das Byte EBCDIC 0x4c Byte nicht das
L
in ASCII ist, sondern tatsächlich ein<
. Ich bin sicher, Sie sehen die Verwirrung hier.Beide Funktionen verwalten EBCDIC, wenn der Webserver es definiert hat.
Außerdem verwenden beide ein Array von Zeichen (Think String Type)
hexchars
, um einige Werte abzurufen. Das Array wird als solches beschrieben:Darüber hinaus sind die Funktionen sehr unterschiedlich und ich werde sie in ASCII und EBCDIC erklären.
Unterschiede in ASCII:
URLENCODE:
+
der Ausgabezeichenfolge ein Vorzeichen hinzu.isalnum(c)
), und auch nicht und_
,-
oder.
Zeichen, dann wir, gibt ein%
Zeichen Feldposition 0, tun einen Array Blick auf die obenhexchars
für eine Referenz für die Array -os_toascii
Anordnung ( Ein Array von Apache, das char in Hex-Code übersetzt) für den Schlüssel vonc
(das vorliegende Zeichen), verschieben wir dann bitweise um 4 nach rechts, weisen diesen Wert dem Zeichen 1 zu und zu Position 2 weisen wir die gleiche Suche zu, außer wir formen vor eine logische und um zu sehen, ob der Wert 15 (0xF) ist, und geben Sie in diesem Fall eine 1 oder eine 0 zurück. Am Ende erhalten Sie etwas Codiertes._-.
Zeichen, gibt es genau das aus, was es ist.RAWURLENCODE:
Hinweis: Viele Programmierer haben wahrscheinlich noch nie gesehen, dass eine for-Schleife auf diese Weise iteriert. Sie ist etwas hackig und nicht die Standardkonvention, die bei den meisten for-Schleifen verwendet wird. Achten Sie darauf, sie weist zu
x
undy
prüft, ob sie beilen
Erreichen von 0 beendet wird, und erhöht sowohlx
als auchy
. Ich weiß, es ist nicht das, was Sie erwarten würden, aber es ist gültiger Code.str
._-.
Zeichen, und wenn dies nicht der Fall, haben wir fast die gleiche Belegung wie bei urlencode wo es Lookups Preforms jedoch erhöhen wir anders verwenden ,y++
anstattto[1]
, ist dies , weil die Saiten werden auf unterschiedliche Weise gebaut, erreichen aber am Ende trotzdem das gleiche Ziel.\0
Byte zugewiesen.Unterschiede:
\0
der Zeichenfolge kein Byte zu, RawUrlEncode jedoch (dies kann ein strittiger Punkt sein).Sie iterieren grundsätzlich anders, man weist bei ASCII 20 ein + -Zeichen zu.
Unterschiede in der EBCDIC:
URLENCODE:
0
, mit Ausnahme eines Wesens.
oder-
, oder weniger als ,A
aber größer als char9
, OR größerZ
und kleiner alsa
eine , aber nicht_
. ODER größer alsz
(ja, EBCDIC ist irgendwie durcheinander, um damit zu arbeiten). Wenn es mit einem dieser Elemente übereinstimmt, führen Sie eine ähnliche Suche wie in der ASCII-Version durch (es ist lediglich keine Suche in os_toascii erforderlich).RAWURLENCODE:
z
sie~
von der URL-Codierung ausgeschlossen wird , wenn sie größer als ist .\0
Byte vor der Rückkehr immer noch an die Zeichenfolge an.Große Zusammenfassung
~
, was UrlEncode nicht tut ( dies ist ein gemeldetes Problem ). Es ist erwähnenswert, dass ASCII und EBCDIC 0x20 beide Leerzeichen sind.+
, RawUrlEncode macht ein Leerzeichen in%20
über Array-Lookups.Haftungsausschluss: Ich habe C seit Jahren nicht mehr berührt und mich EBCDIC schon lange nicht mehr angesehen. Wenn ich irgendwo falsch liege, lass es mich wissen.
Vorgeschlagene Implementierungen
Basierend auf all dem ist Rawurlencode die meiste Zeit der richtige Weg. Wie Sie in Jonathan Finglands Antwort sehen, bleiben Sie in den meisten Fällen dabei. Es befasst sich mit dem modernen Schema für URI-Komponenten, bei dem Urlencode die Dinge auf die alte Art und Weise erledigt, wobei + "Raum" bedeutet.
Wenn Sie versuchen, zwischen dem alten und dem neuen Format zu konvertieren, stellen Sie sicher, dass Ihr Code nicht fehlerhaft ist, und verwandeln Sie etwas, das ein dekodiertes + Zeichen ist, in ein Leerzeichen, indem Sie es versehentlich doppelt codieren, oder ähnliche "oops" -Szenarien Platz / 20% / + Ausgabe.
Wenn Sie auf einem älteren System mit älterer Software arbeiten, die das neue Format nicht bevorzugt, bleiben Sie bei Urlencode. Ich glaube jedoch, dass% 20 tatsächlich abwärtskompatibel ist, da% 20 unter dem alten Standard einfach nicht funktioniert hat bevorzugt. Probieren Sie es aus, wenn Sie zum Herumspielen bereit sind. Lassen Sie uns wissen, wie es für Sie funktioniert hat.
Grundsätzlich sollten Sie bei raw bleiben, es sei denn, Ihr EBCDIC-System hasst Sie wirklich. Die meisten Programmierer werden auf keinem System, das nach dem Jahr 2000, vielleicht sogar 1990, hergestellt wurde, auf EBCDIC stoßen (das ist drängend, aber meiner Meinung nach immer noch wahrscheinlich).
quelle
ergibt
während
ergibt
Der Unterschied ist der
asd%20asd
vsasd+asd
urlencode unterscheidet sich von RFC 1738 durch die Codierung von Leerzeichen
+
anstelle von%20
quelle
Ein praktischer Grund, einen über den anderen zu wählen, besteht darin, das Ergebnis in einer anderen Umgebung zu verwenden, beispielsweise in JavaScript.
In PHP wird
urlencode('test 1')
zurückgegeben,'test+1'
währendrawurlencode('test 1')
zurückgegeben wird'test%201'
als Ergebnis.Wenn Sie dies jedoch in JavaScript mit der Funktion decodeURI () "dekodieren"
decodeURI("test+1")
müssen, erhalten Sie,"test+1"
währenddecodeURI("test%201")
Sie"test 1"
das Ergebnis erhalten.Mit anderen Worten, der von urlencode bis plus ("+") in PHP codierte Leerzeichen ("") wird von decodeURI in JavaScript nicht ordnungsgemäß decodiert .
In solchen Fällen sollte die Rawurlencode- PHP-Funktion verwendet werden.
quelle
json_encode
undJSON.parse
zu diesem Zweck.Ich glaube, Leerzeichen müssen wie folgt codiert werden:
%20
bei Verwendung innerhalb der URL-Pfadkomponente+
bei Verwendung innerhalb von URL- Abfragezeichenfolgenkomponenten oder Formulardaten (siehe 17.13.4 Formularinhaltstypen )Das folgende Beispiel zeigt die korrekte Verwendung von
rawurlencode
undurlencode
:Ausgabe:
Was passiert, wenn Sie Pfad- und Abfragezeichenfolgenkomponenten umgekehrt codieren? Für das folgende Beispiel:
latest+songs
stattdessen nach dem Verzeichnislatest songs
q
enthältlady gaga
quelle
q
enthältlady gaga
" Was würde er sonst noch enthalten? Der Abfrageparameterq
scheint$_GET
unabhängig von der Verwendung denselben Wert an das Array übergeben zu habenrawurlencode
oderurlencode
in PHP 5.2+ übergeben zu haben. Obwohl,urlencode
codiert in demapplication/x-www-form-urlencoded
Format , das standardmäßig für GET - Anfragen ist , damit ich mit dem Ansatz gehe. +1+
und%20
als Leerzeichen dekodiert werden, wenn sie in Abfragezeichenfolgen verwendet werden.Der Unterschied liegt in den Rückgabewerten, dh:
urlencode () :
rawurlencode () :
Die beiden sind sich sehr ähnlich, aber letztere (rawurlencode) ersetzen Leerzeichen durch ein '%' und zwei hexadezimale Ziffern, was zum Codieren von Passwörtern oder dergleichen geeignet ist, wobei ein '+' nicht z.
quelle
1. Was genau sind die Unterschiede und
Der einzige Unterschied besteht in der Art und Weise, wie Räume behandelt werden:
urlencode - basierend auf der Legacy-Implementierung konvertiert Leerzeichen in +
rawurlencode - basierend auf RFC 1738 übersetzt Leerzeichen in% 20
Der Grund für den Unterschied ist, dass + in URLs reserviert und gültig (nicht codiert) ist.
2. welches ist bevorzugt?
Fairerweise habe ich eine einfache Strategie, die ich bei diesen Entscheidungen verfolge und die ich mit Ihnen teilen werde, in der Hoffnung, dass sie helfen kann.
Ich denke, es war die HTTP / 1.1-Spezifikation RFC 2616, die " tolerante Anwendungen " forderte.
Bei solchen Fragen besteht die beste Strategie immer darin, so viel wie möglich zu konsumieren und Standards zu produzieren, die den Standards entsprechen.
Mein Rat ist daher
rawurlencode
, standardkonforme RFC 1738-codierte Zeichenfolgenurldecode
zu erstellen und abwärtskompatibel zu sein und alles zu berücksichtigen, was Sie möglicherweise verbrauchen.Jetzt könnten Sie einfach mein Wort dafür nehmen, aber lassen Sie uns beweisen, dass wir ...
Es scheint, dass PHP genau dies im Sinn hatte, obwohl ich noch nie auf jemanden gestoßen bin, der eines der beiden Formate ablehnt, kann ich mir keine bessere Strategie als Ihre Defacto-Strategie vorstellen, oder?
nJoy!
quelle
quelle
Leerzeichen codiert als
%20
vs.+
Der Hauptgrund, den ich
rawurlencode()
in den meisten Fällen gesehen habe, ist, dassurlencode
Texträume als+
(Pluszeichen)rawurlencode
codiert werden, wobei sie als häufig gesehen codiert werden%20
:Ich habe speziell bestimmte API-Endpunkte gesehen, die codierte Textabfragen akzeptieren, die
%20
für ein Leerzeichen erwartet werden, und daher fehlschlagen, wenn stattdessen ein Pluszeichen verwendet wird. Offensichtlich wird dies zwischen API-Implementierungen unterschiedlich sein und Ihr Kilometerstand kann variieren.quelle
Ich glaube, Urlencode ist für Abfrageparameter, während der Rawurlencode für die Pfadsegmente ist. Dies ist hauptsächlich auf
%20
Pfadsegmente+
und Abfrageparameter zurückzuführen. Siehe diese Antwort, die über die Räume spricht: Wann muss das Leerzeichen in Plus (+) oder% 20 codiert werden?Funktioniert
%20
jetzt jedoch auch in Abfrageparametern, weshalb rawurlencode immer sicherer ist. Das Pluszeichen wird jedoch häufig verwendet, wenn die Benutzererfahrung bei der Bearbeitung und Lesbarkeit von Abfrageparametern von Bedeutung ist.Beachten Sie, dass dies bedeutet,
rawurldecode
dass nicht+
in Leerzeichen dekodiert wird ( http://au2.php.net/manual/en/function.rawurldecode.php ). Aus diesem Grund wird $ _GET immer automatisch durchlaufenurldecode
, was bedeutet, dass+
und%20
beide in die Räume decodiert.Wenn Sie möchten, dass die Codierung und Decodierung zwischen Ein- und Ausgängen konsistent ist und Sie ausgewählt haben, dass sie immer
+
und nicht%20
für Abfrageparameter verwendet werden sollen, dannurlencode
ist dies für Abfrageparameter (Schlüssel und Wert) in Ordnung.Die Schlussfolgerung lautet:
Pfadsegmente - verwenden Sie immer rawurlencode / rawurldecode
Abfrageparameter - Verwenden Sie zum Decodieren immer den URL-Code (automatisch). Für die Codierung ist sowohl der Rawurlencode als auch der Urlencode in Ordnung. Wählen Sie einfach einen aus, um konsistent zu sein, insbesondere beim Vergleichen von URLs.
quelle
simple * rawurlencode der Pfad - Pfad ist der Teil vor dem "?" - Leerzeichen müssen als% 20 * urlencode der Abfragezeichenfolge codiert werden. - Abfragezeichenfolge ist der Teil nach dem "?" -spaces sind besser codiert als "+" = rawurlencode ist im Allgemeinen kompatibler
quelle