Si je veux créer une URL en utilisant une variable, j'ai deux choix pour encoder la chaîne. urlencode()
et rawurlencode()
.
Quelles sont exactement les différences et qui est préféré?
Si je veux créer une URL en utilisant une variable, j'ai deux choix pour encoder la chaîne. urlencode()
et rawurlencode()
.
Quelles sont exactement les différences et qui est préféré?
Cela dépendra de votre objectif. Si l'interopérabilité avec d'autres systèmes est important, alors il semble rawurlencode est le chemin à parcourir. La seule exception est l'héritage des systèmes qui attendent la chaîne de requête pour suivre la forme-le style d'encodage des espaces codés comme des + au lieu de %20 (dans ce cas, vous avez besoin de la fonction urlencode).
rawurlencode suit RFC 1738 avant PHP 5.3.0 et RFC 3986 par la suite (voir http://us2.php.net/manual/en/function.rawurlencode.php)
Renvoie une chaîne dans laquelle tous les caractères non-alphanumériques sauf -_.~ ont été remplacés par un pourcentage (%) signe suivi de deux chiffres hexadécimaux. C'est l'encodage décrit dans la » RFC 3986 pour la protection des caractères interprétés comme des URL spéciale délimiteurs, et pour protéger Url mutilé par des supports de transmission avec les conversions de caractères (comme certains systèmes de messagerie).
Note sur la RFC 3986 vs 1738. rawurlencode avant php 5.3 codé le caractère tilde (~
) selon la RFC 1738. Depuis PHP 5.3, cependant, rawurlencode suit RFC 3986 qui ne nécessite pas de codage tilde caractères.
urlencode code pour les espaces comme des signes plus (pas comme %20
comme le fait le rawurlencode)(voir http://us2.php.net/manual/en/function.urlencode.php)
Renvoie une chaîne dans laquelle tous les caractères non-alphanumériques sauf -_. ont été remplacés par un pourcentage (%) signe suivi de deux chiffres hexadécimaux et des espaces codés comme des signes plus ( + ). Il est codé de la même manière que les données publiées, à partir d'un formulaire web est codé, qui est de la même manière que dans l'application/x-www-form-urlencoded type de média. Cela diffère de la » RFC 3986 de codage (voir rawurlencode()) que pour des raisons historiques, les espaces sont codés comme des signes plus ( + ).
Cela correspond à la définition de l'application/x-www-form-urlencoded dans la RFC 1866.
Lectures Supplémentaires:
Vous pouvez également voir la discussion à http://bytes.com/groups/php/5624-urlencode-vs-rawurlencode.
Aussi, la RFC 2396 vaut le coup d'oeil. La RFC 2396 définit l'URI valide la syntaxe. La partie principale qui nous intéresse, c'est de 3,4 Composant de Requête:
Au sein d'un composant de requête, les personnages
";", "/", "?", ":", "@",
sont réservés.
Comme vous pouvez le voir, l'
est un caractère réservé dans la chaîne de requête, et, donc, doivent être codées conformément à la RFC 3986 (comme dans rawurlencode).
La preuve est dans le code source de PHP.
Je vais vous emmener à travers un processus rapide de la façon de trouver ce genre de chose sur votre propre, dans l'avenir, à tout moment vous voulez. Ours avec moi, il y a beaucoup de code source C, vous pouvez effleurer (je l'expliquer). Si vous voulez pinceau sur un peu de C, un bon endroit pour commencer est de notre wiki.
Télécharger de la source (ou de l'utilisation http://lxr.php.net/ le parcourir en ligne), grep tous les fichiers pour le nom de la fonction, vous trouverez quelque chose comme ceci:
PHP 5.3.6 (les plus récentes au moment de la rédaction) décrit les deux fonctions dans leur propre C de code dans le fichier url.c.
RawUrlEncode()
PHP_FUNCTION(rawurlencode)
{
char *in_str, *out_str;
int in_str_len, out_str_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &in_str,
&in_str_len) == FAILURE) {
return;
}
out_str = php_raw_url_encode(in_str, in_str_len, &out_str_len);
RETURN_STRINGL(out_str, out_str_len, 0);
}
La fonction UrlEncode()
PHP_FUNCTION(urlencode)
{
char *in_str, *out_str;
int in_str_len, out_str_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &in_str,
&in_str_len) == FAILURE) {
return;
}
out_str = php_url_encode(in_str, in_str_len, &out_str_len);
RETURN_STRINGL(out_str, out_str_len, 0);
}
Ok, donc ce qui est différent ici?
Ils sont, en substance, appelant les deux différentes fonctions internes respectivement: php_raw_url_encode et php_url_encode
Allez donc regarder pour ces fonctions!
PHPAPI char *php_raw_url_encode(char const *s, int len, int *new_length)
{
register int x, y;
unsigned char *str;
str = (unsigned char *) safe_emalloc(3, len, 1);
for (x = 0, y = 0; len--; x++, y++) {
str[y] = (unsigned char) s[x];
#ifndef CHARSET_EBCDIC
if ((str[y] < '0' && str[y] != '-' && str[y] != '.') ||
(str[y] < 'A' && str[y] > '9') ||
(str[y] > 'Z' && str[y] < 'a' && str[y] != '_') ||
(str[y] > 'z' && str[y] != '~')) {
str[y++] = '%';
str[y++] = hexchars[(unsigned char) s[x] >> 4];
str[y] = hexchars[(unsigned char) s[x] & 15];
#else /*CHARSET_EBCDIC*/
if (!isalnum(str[y]) && strchr("_-.~", str[y]) != NULL) {
str[y++] = '%';
str[y++] = hexchars[os_toascii[(unsigned char) s[x]] >> 4];
str[y] = hexchars[os_toascii[(unsigned char) s[x]] & 15];
#endif /*CHARSET_EBCDIC*/
}
}
str[y] = '\0';
if (new_length) {
*new_length = y;
}
return ((char *) str);
}
PHPAPI char *php_url_encode(char const *s, int len, int *new_length)
{
register unsigned char c;
unsigned char *to, *start;
unsigned char const *from, *end;
from = (unsigned char *)s;
end = (unsigned char *)s + len;
start = to = (unsigned char *) safe_emalloc(3, len, 1);
while (from < end) {
c = *from++;
if (c == ' ') {
*to++ = '+';
#ifndef CHARSET_EBCDIC
} else if ((c < '0' && c != '-' && c != '.') ||
(c < 'A' && c > '9') ||
(c > 'Z' && c < 'a' && c != '_') ||
(c > 'z')) {
to[0] = '%';
to[1] = hexchars[c >> 4];
to[2] = hexchars[c & 15];
to += 3;
#else /*CHARSET_EBCDIC*/
} else if (!isalnum(c) && strchr("_-.", c) == NULL) {
/* Allow only alphanumeric chars and '_', '-', '.'; escape the rest */
to[0] = '%';
to[1] = hexchars[os_toascii[c] >> 4];
to[2] = hexchars[os_toascii[c] & 15];
to += 3;
#endif /*CHARSET_EBCDIC*/
} else {
*to++ = c;
}
}
*to = 0;
if (new_length) {
*new_length = to - start;
}
return (char *) start;
}
Rapide, peu de connaissances avant de m'avancer, EBCDIC est un autre jeu de caractères, semblable à l'ASCII, mais un total concurrent. PHP tente de composer avec les deux. Mais fondamentalement, cela signifie octet EBCDIC 0x4c octet n'est pas l' L
en ASCII, c'est en fait un <
. Je suis sûr que vous voyez la confusion ici.
Ces deux fonctions gérer EBCDIC si le serveur web a défini.
Aussi, ils utilisent tous les deux un tableau de caractères (pensez au type de chaîne) hexchars
de recherche pour obtenir des valeurs, le tableau est décrit comme tel:
/* rfc1738:
...The characters ";",
"/", "?", ":", "@", "=" and "&" are the characters which may be
reserved for special meaning within a scheme...
...Thus, only alphanumerics, the special characters "$-_.+!*'(),", and
reserved characters used for their reserved purposes may be used
unencoded within a URL...
For added safety, we only leave -_. unencoded.
*/
static unsigned char hexchars[] = "0123456789ABCDEF";
Au-delà, les fonctions sont vraiment différents, et je vais expliquer en ASCII et EBCDIC.
URLENCODE:
+
signe de la chaîne de sortie.isalnum(c)
), et n'est pas également et _
, -
ou .
caractère, puis nous , sortie de une %
signe de la matrice de la position 0, faire un tableau regarde à l' hexchars
tableau pour une liste de choix pour os_toascii
tableau (un tableau à partir d' Apache qui se traduit par char à code hex) pour la clé de c
(le caractère actuel), nous avons ensuite au niveau du bit décalage à droite par 4, affecter cette valeur à l'caractères 1 et position 2 nous attribuer la même recherche, sauf que nous préforme dans une logique de voir si la valeur est de 15 (0xF), et retour à 1 dans ce cas, ou 0 sinon. À la fin, vous vous retrouverez avec quelque chose de codé._-.
caractères, il génère exactement ce que c'est.RAWURLENCODE:
Remarque: de Nombreux programmeurs n'ont probablement jamais vu une boucle pour parcourir cette façon, il est un peu hackish et non pas à la convention standard utilisé avec la plupart pour des boucles, attention, il attribue x
et y
, les contrôles pour la sortie sur len
d'atteindre 0, et incrémente les deux x
et y
. Je sais, ce n'est pas ce que vous attendez, mais c'est le code valide.
str
._-.
caractères, et si elle ne l'est pas, nous le faisons presque la même mission qu'avec URLENCODE où il préformes recherches, cependant, on incrémente de façon différente, avec y++
plutôt que d' to[1]
, c'est parce que les cordes sont en train d'être construit de différentes façons, mais atteindre le même objectif à la fin de toute façon.\0
octet. Différences:
\0
d'octets de la chaîne, RawUrlEncode (cela peut être un point discutable)En gros, ils itérer différemment, on attribue un signe + dans le cas de l'ASCII 20.
URLENCODE:
0
, à l'exception de la un .
ou -
, OU moins de A
mais de plus de char 9
, OU de plus de Z
et moins de a
mais pas un _
. OU supérieure à z
(ouais, EBCDIC est un peu foiré à travailler). Si elle correspond à l'un de ces, faire une semblable recherche, comme dans la version ASCII (il n'a tout simplement pas besoin d'une recherche dans os_toascii).RAWURLENCODE:
z
, il exclut ~
à partir de l'URL de l'encodage.\0
d'octets de la chaîne avant le retour.~
que UrlEncode ne le fait pas (c'est une question). Il est intéressant de noter que l'ASCII et EBCDIC 0x20 sont les deux espaces.+
, RawUrlEncode fait d'un espace en %20
via la matrice de recherches.Avertissement: je n'ai pas touché C depuis des années, et je n'ai pas regardé EBCDIC dans un très très long moment. Si je me trompe quelque part, laissez-moi savoir.
Basé sur tout cela, rawurlencode est la façon de passer la plupart du temps. Comme vous le voyez dans Jonathan Fingland réponse, rester avec elle dans la plupart des cas. Il traite avec le schéma moderne pour URI composants, où que urlencode fait des choses de la old school, où " + " signifie "espace".
Si vous essayez de convertir entre l'ancien format et de nouveaux formats, assurez-vous que votre code n'est pas gaffe et tourner à quelque chose qui est décodé signe + dans l'espace par mégarde le double encodage, ou similaire "oups" scénarios autour de cet espace/20%/+ question.
Si vous travaillez sur un ancien système avec des logiciels plus anciens qui ne préfère pas le nouveau format, le bâton avec urlencode, je crois cependant qu' %20 sera effectivement compatible, comme sous l'ancienne norme %20 travaillé, je n'ai pas de préférence. Donner un coup de feu si vous êtes pour jouer, laissez-nous savoir comment il a travaillé pour vous.
Fondamentalement, vous devriez coller avec la matière première, à moins que votre EBCDIC système vraiment vous hait. La plupart des programmeurs ne sera jamais exécuté en EBCDIC sur tout autre système après l'an 2000, peut-être même des années 1990 (qui pousse, mais toujours probable à mon avis).
echo rawurlencode('http://www.google.com/index.html?id=asd asd');
rendements
http%3A%2F%2Fwww.google.com%2Findex.html%3Fid%3Dasd%20asd
tandis que
echo urlencode('http://www.google.com/index.html?id=asd asd');
rendements
http%3A%2F%2Fwww.google.com%2Findex.html%3Fid%3Dasd+asd
La différence étant le asd%20asd
vs asd+asd
urlencode diffère de RFC 1738 en codant des espaces comme +
au lieu de %20
Une raison pratique pour choisir entre l'un ou l'autre est si vous allez utiliser le résultat dans un autre environnement, par exemple en JavaScript.
En PHP urlencode('test 1')
retours 'test+1'
tout rawurlencode('test 1')
retours 'test%201'
comme résultat.
Mais si vous avez besoin de "décoder" ce en JavaScript à l'aide de decodeURI() fonction d' decodeURI("test+1")
vous donnera "test+1"
tout decodeURI("test%201")
vous donnera "test 1"
comme résultat.
En d'autres termes, l'espace (" ") codée par urlencode de plus ("+") en PHP ne sera pas correctement décodé par decodeURI en JavaScript.
Dans de tels cas, le rawurlencode fonction PHP doit être utilisé.
Je crois que les espaces doivent être codées comme:
%20
lorsqu'il est utilisé dans l'URL du chemin+
lorsqu'il est utilisé dans l'URL de requête composant ou de la forme des données (voir 17.13.4 Forme de types de contenu)L'exemple suivant montre l'utilisation correcte de l' rawurlencode
et urlencode
:
echo "http://example.com"
. "/category/" . rawurlencode("latest songs")
. "/search?q=" . urlencode("lady gaga");
Sortie:
http://example.com/category/latest%20songs/search?q=lady+gaga
Qu'advient-il si vous encodez chemin d'accès et la chaîne de requête de composants dans l'autre sens? Pour l'exemple suivant:
http://example.com/category/latest+songs/search?q=lady%20gaga
latest+songs
au lieu de latest songs
q
contiendra lady gaga
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.