urlencode vs rawurlencode?

380

Si je veux créer une URL à l'aide d'une variable, j'ai deux choix pour encoder la chaîne. urlencode()et rawurlencode().

Quelles sont exactement les différences et laquelle est préférée?

Gary Willoughby
la source
1
J'aimerais vraiment voir quelques raisons de choisir l'une plutôt que l'autre (par exemple, des problèmes qui pourraient être rencontrés avec l'un ou l'autre), je (et j'attends d'autres) veulent pouvoir en choisir une et l'utiliser à tout jamais avec le moins de bruit, donc j'ai commencé une prime sur cette question.
Kzqai
29
@Tchalvak: Si vous ne voulez en choisir qu'un, choisissez rawurlencode. Vous rencontrerez rarement un système qui s'étouffe lorsque des espaces sont codés en tant que %20, alors que les systèmes qui s'étouffent sur des espaces codés en +sont plus courants.
Anomie

Réponses:

326

Cela dépendra de votre objectif. Si l'interopérabilité avec d'autres systèmes est importante, il semble que le rawurlencode soit la voie à suivre. La seule exception concerne les systèmes hérités qui s'attendent à ce que la chaîne de requête suive le style de codage de forme des espaces codés comme + au lieu de% 20 (auquel cas vous avez besoin du code url).

rawurlencode suit RFC 1738 avant PHP 5.3.0 et RFC 3986 après (voir http://us2.php.net/manual/en/function.rawurlencode.php )

Renvoie une chaîne dans laquelle tous les caractères non alphanumériques à l'exception de -_. ~ Ont été remplacés par un signe de pourcentage (%) suivi de deux chiffres hexadécimaux. Il s'agit du codage décrit dans la »RFC 3986 pour protéger les caractères littéraux d'être interprétés comme des délimiteurs d'URL spéciaux, et pour protéger les URL contre la mutilation par les supports de transmission avec des conversions de caractères (comme certains systèmes de messagerie).

Remarque sur RFC 3986 vs 1738. rawurlencode avant php 5.3 encodait le caractère tilde ( ~) selon RFC 1738. Cependant, depuis PHP 5.3, rawurlencode suit RFC 3986 qui ne nécessite pas d'encodage de caractères tilde.

urlencode code les espaces sous forme de signes plus (pas comme %20dans rawurlencode) (voir http://us2.php.net/manual/en/function.urlencode.php )

Renvoie une chaîne dans laquelle tous les caractères non alphanumériques à l'exception de -_. ont été remplacés par un signe de pourcentage (%) suivi de deux chiffres hexadécimaux et d'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 WWW sont codées, c'est-à-dire de la même manière que dans le type de support application / x-www-form-urlencoded. Cela diffère du codage »RFC 3986 (voir rawurlencode ()) en ce que pour des raisons historiques, les espaces sont codés sous forme de signes plus (+).

Cela correspond à la définition de l'application / x-www-form-urlencoded dans la RFC 1866 .

Lecture supplémentaire:

Vous pouvez également souhaiter voir la discussion sur http://bytes.com/groups/php/5624-urlencode-vs-rawurlencode .

En outre, la RFC 2396 vaut le détour. La RFC 2396 définit une syntaxe URI valide. La partie principale qui nous intéresse est de 3.4 Composant de requête:

Dans un composant de requête, les caractères sont réservés.";", "/", "?", ":", "@",
"&", "=", "+", ",", and "$"

Comme vous pouvez le voir, le +est un caractère réservé dans la chaîne de requête et devrait donc être codé selon RFC 3986 (comme dans rawurlencode).

Jonathan Fingland
la source
27
Alors, qui est préféré?
Gary Willoughby
79
rawurlencode. aller avec la norme dans ce cas. urlencode n'est conservé que pour une utilisation héritée
Jonathan Fingland
2
Grand merci, c'est ce que je pensais, je voulais juste un deuxième avis avant de commencer à mettre à jour beaucoup de code.
Gary Willoughby
3
Je pense que c'est du rawurlencode qui n'encode pas les espaces comme des signes plus mais comme% 20s
BigName
2
@Pindatjuh: La partie que vous avez citée La seule exception concerne les systèmes hérités qui s'attendent à ce que la chaîne de requête suive le style d'encodage des espaces codés en + au lieu de% 20 (auquel cas vous avez besoin d'urlencode) signifie que, tandis que rawurlencode convient à la plupart des situations , certains systèmes s'attendent à ce que les espaces soient codés comme un + (signe plus). Pour de tels systèmes, l'urlencode est le meilleur choix.
Jonathan Fingland
213

La preuve est dans le code source de PHP.

Je vais vous guider à travers un processus rapide sur la façon de découvrir ce genre de chose par vous-même à l'avenir à tout moment. Soyez avec moi, il y aura beaucoup de code source C que vous pouvez parcourir (je l'explique). Si vous voulez rafraîchir certains C, un bon endroit pour commencer est notre wiki SO .

Téléchargez la source (ou utilisez http://lxr.php.net/ pour la parcourir en ligne), grep tous les fichiers pour le nom de la fonction, vous trouverez quelque chose comme ceci:

PHP 5.3.6 ( le plus récent au moment de la rédaction) décrit les deux fonctions dans leur code natif C 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);
}

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);
}

D'accord, alors qu'est-ce qui est différent ici?

Ils appellent tous deux essentiellement deux fonctions internes différentes respectivement: php_raw_url_encode et php_url_encode

Alors allez chercher ces fonctions!

Regardons php_raw_url_encode

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);
}

Et bien sûr, php_url_encode:

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;
}

Un peu de connaissances avant d'aller de l'avant, EBCDIC est un autre jeu de caractères , similaire à ASCII, mais un concurrent total. PHP tente de gérer les deux. Mais en gros, cela signifie que l'octet EBCDIC 0x4c n'est pas Len ASCII, c'est en fait un <. Je suis sûr que vous voyez la confusion ici.

Ces deux fonctions gèrent EBCDIC si le serveur Web l'a défini.

En outre, ils utilisent tous les deux un tableau de recherche de caractères (pensez au type de chaîne) hexcharspour obtenir certaines 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à de cela, les fonctions sont vraiment différentes, et je vais les expliquer en ASCII et EBCDIC.

Différences en ASCII:

URLENCODE:

  • Calcule une longueur de début / fin de la chaîne d'entrée, alloue de la mémoire
  • Parcourt une boucle while, incrémente jusqu'à atteindre la fin de la chaîne
  • Saisit le personnage actuel
  • Si le caractère est égal au caractère ASCII 0x20 (c'est-à-dire un "espace"), ajoutez un +signe à la chaîne de sortie.
  • Si ce n'est pas un espace, et ce n'est pas non plus alphanumérique ( isalnum(c)), et n'est pas non plus et _, -ou un .caractère, alors nous, sortons un %signe à la position 0 du tableau, faisons un hexcharstableau pour rechercher le os_toasciitableau ( un tableau d' Apache qui traduit char en code hexadécimal) pour la clé de c(le caractère actuel), nous décalons ensuite bit à droite de 4, affectons cette valeur au caractère 1, et à la position 2 nous attribuons la même recherche, sauf que nous préformons un logique et pour voir si la valeur est 15 (0xF), et retourner un 1 dans ce cas, ou un 0 sinon. À la fin, vous vous retrouverez avec quelque chose d'encodé.
  • S'il finit par ne pas être un espace, c'est alphanumérique ou l'un des _-.caractères, il sort exactement ce que c'est.

RAWURLENCODE:

  • Alloue de la mémoire pour la chaîne
  • Itère dessus en fonction de la longueur fournie dans l'appel de fonction (non calculé dans la fonction comme avec URLENCODE).

Remarque: De nombreux programmeurs n'ont probablement jamais vu d'itération de boucle for de cette façon, c'est quelque peu hack et non la convention standard utilisée avec la plupart des boucles for, faites attention, il attribue xet yvérifie la sortie en lenatteignant 0 et incrémente les deux xet y. Je sais, ce n'est pas ce que vous attendez, mais c'est un code valide.

  • Attribue le caractère actuel à une position de caractère correspondante dans str.
  • Il vérifie si le caractère actuel est alphanumérique ou l'un des _-.caractères, et s'il ne l'est pas, nous faisons presque la même affectation qu'avec URLENCODE où il préforme les recherches, cependant, nous incrémentons différemment, en utilisant y++plutôt que to[1], c'est parce que le les cordes sont construites de différentes manières, mais atteignent le même objectif à la fin de toute façon.
  • Lorsque la boucle est terminée et que la longueur a disparu, il termine en fait la chaîne, attribuant l' \0octet.
  • Il renvoie la chaîne codée.

Différences:

  • UrlEncode vérifie l'espace, attribue un signe +, RawURLEncode non.
  • UrlEncode n'affecte pas d' \0octet à la chaîne, RawUrlEncode le fait (cela peut être un point discutable)
  • Ils itèrent différemment, on peut avoir tendance à déborder avec des chaînes mal formées, je suggère simplement cela et je n'ai pas réellement enquêté.

Ils itèrent fondamentalement différemment, on attribue un signe + en cas d'ASCII 20.

Différences dans EBCDIC:

URLENCODE:

  • Même configuration d'itération qu'avec ASCII
  • Toujours traduire le caractère "espace" en signe + . Remarque - Je pense que cela doit être compilé dans EBCDIC ou vous vous retrouverez avec un bogue? Quelqu'un peut-il modifier et confirmer cela?
  • Il vérifie si le caractère actuel est un caractère avant 0, à l'exception d'être un .ou -, OU inférieur Amais supérieur à caractère 9, OU supérieur Zet inférieur à amais non a _. OU supérieur à z(ouais, EBCDIC est un peu foiré de travailler avec). S'il correspond à l'un d'entre eux, effectuez une recherche similaire à celle trouvée dans la version ASCII (cela ne nécessite tout simplement pas de recherche dans os_toascii).

RAWURLENCODE:

  • Même configuration d'itération qu'avec ASCII
  • Même vérification que celle décrite dans la version EBCDIC du codage d'URL, à l'exception que si elle est supérieure à z, elle exclut ~du codage d'URL.
  • Même affectation que le code ASCII RawUrlEncode
  • Ajoutant toujours l' \0octet à la chaîne avant le retour.

Grand résumé

  • Les deux utilisent la même table de recherche hexchars
  • URIEncode ne termine pas une chaîne avec \ 0, brut le fait.
  • Si vous travaillez dans EBCDIC, je vous suggère d'utiliser RawUrlEncode, car il gère ce ~que UrlEncode ne fait pas ( il s'agit d'un problème signalé ). Il convient de noter que ASCII et EBCDIC 0x20 sont tous deux des espaces.
  • Ils itèrent différemment, l'un peut être plus rapide, l'autre peut être sujet à des exploits basés sur la mémoire ou les chaînes.
  • URIEncode crée un espace +, RawUrlEncode crée un espace %20via des recherches de tableau.

Avertissement: je n'ai pas touché C depuis des années et je n'ai pas regardé EBCDIC depuis très très longtemps. Si je me trompe quelque part, faites le moi savoir.

Implémentations suggérées

Sur la base de tout cela, le rawurlencode est la voie à suivre la plupart du temps. Comme vous le voyez dans la réponse de Jonathan Fingland, respectez-la dans la plupart des cas. Il traite du schéma moderne pour les composants URI, où comme l'urlencode fait les choses à l'ancienne, où + signifiait «espace».

Si vous essayez de convertir entre l'ancien format et les nouveaux formats, assurez-vous que votre code ne se gâte pas et ne transforme pas quelque chose qui est un signe + décodé en espace en double-encodant accidentellement, ou des scénarios similaires "oops" autour de ce espace / 20% / + problème.

Si vous travaillez sur un système plus ancien avec un logiciel plus ancien qui ne préfère pas le nouveau format, restez avec le code url, cependant, je pense que% 20 sera en fait rétrocompatible, comme sous l'ancien standard% 20 fonctionnait, n'était tout simplement pas préféré. Essayez-le si vous êtes prêt à jouer, faites-nous savoir comment cela a fonctionné pour vous.

Fondamentalement, vous devriez vous en tenir au raw, à moins que votre système EBCDIC ne vous déteste vraiment. La plupart des programmeurs ne rencontreront jamais EBCDIC sur un système fabriqué après l'an 2000, peut-être même 1990 (c'est poussant, mais toujours probable à mon avis).

Incognito
la source
Je n'ai jamais eu à me soucier du double encodage après tout, je devrais savoir ce que j'ai encodé car c'est moi qui fais l'encodage, je pense. Depuis que je décode tout ce que je reçois avec un mode de compatibilité qui sait comment traiter + pour l'espace, je n'ai également jamais rencontré les problèmes que vous essayez d'avertir ici. Je peux comprendre en regardant la source si nous ne savons pas ce que fait quelque chose, mais qu'avons-nous appris exactement ici que nous ne savions pas déjà en exécutant simplement les deux fonctions. Je sais que je suis partial mais je ne peux pas m'empêcher de penser que cela est allé trop loin. Bravo cependant! =)
nickl-
2
+1, pour cette partie: "Je crois que% 20 sera en fait rétrocompatible, comme sous l'ancien% 20 fonctionnait, n'était tout simplement pas préféré"
Gras Double
3
Bonne réponse, mais peut-être un peu exagéré?
rinogo
38
echo rawurlencode('http://www.google.com/index.html?id=asd asd');

les 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');

les rendements

http%3A%2F%2Fwww.google.com%2Findex.html%3Fid%3Dasd+asd

La différence étant le asd%20asdvsasd+asd

urlencode diffère de RFC 1738 par l'encodage des espaces au +lieu de%20

gigue
la source
28

Une raison pratique de choisir l'un plutôt que l'autre est que vous allez utiliser le résultat dans un autre environnement, par exemple JavaScript.

En PHP urlencode('test 1')retourne 'test+1'tout rawurlencode('test 1')retourne 'test%201'comme résultat.

Mais si vous avez besoin de "décoder" cela en JavaScript en utilisant la fonction decodeURI () , decodeURI("test+1")vous obtiendrez "test+1"alors que vous decodeURI("test%201")obtiendrez "test 1"le résultat.

En d'autres termes, l'espace ("") encodé par urlencode en plus ("+") en PHP ne sera pas correctement décodé par decodeURI en JavaScript.

Dans de tels cas, la fonction PHP rawurlencode doit être utilisée.

Neven Boyanov
la source
6
C'est de loin la meilleure réponse que j'ai vue. Il fournit une suggestion d'utilisation, en arrière par un exemple du monde réel. De plus, il est concis.
dotancohen
C'est un bel exemple, bien que je préfère json_encodeet JSON.parseà cette fin.
Fabrício Matté
21

Je crois que les espaces doivent être codés comme:

  • %20 lorsqu'il est utilisé dans le composant de chemin d'URL
  • +lorsqu'il est utilisé à l'intérieur d'un composant de chaîne de requête d'URL ou de données de formulaire (voir 17.13.4 Types de contenu de formulaire )

L'exemple suivant montre l'utilisation correcte de rawurlencodeet urlencode:

echo "http://example.com"
    . "/category/" . rawurlencode("latest songs")
    . "/search?q=" . urlencode("lady gaga");

Production:

http://example.com/category/latest%20songs/search?q=lady+gaga

Que se passe-t-il si vous codez le chemin d'accès et interrogez les composants de chaîne dans l'autre sens? Pour l'exemple suivant:

http://example.com/category/latest+songs/search?q=lady%20gaga
  • Le serveur Web recherchera le répertoire latest+songsau lieu delatest songs
  • Le paramètre de chaîne de requête qcontiendralady gaga
Salman A
la source
2
"Le paramètre de chaîne de requête qcontiendra lady gaga" Que contient-il d'autre sinon? Le paramètre de requête qsemble avoir la même valeur transmise au $_GETtableau indépendamment de l'utilisation rawurlencodeou urlencodede PHP 5.2+. Bien que, urlencodecode dans le application/x-www-form-urlencodedformat qui est par défaut pour les demandes GET, je vais donc avec votre approche. +1
Fabrício Matté
2
Je voulais préciser que les deux +et %20sont décodés comme espace lorsqu'ils sont utilisés dans des chaînes de requête.
Salman A
5

La différence réside dans les valeurs de retour, c'est-à-dire:

urlencode () :

Renvoie une chaîne dans laquelle tous les caractères non alphanumériques à l'exception de -_. ont été remplacés par un signe de pourcentage (%) suivi de deux chiffres hexadécimaux et d'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 WWW sont codées, c'est-à-dire de la même manière que dans le type de support application / x-www-form-urlencoded. Cela diffère du codage »RFC 1738 (voir rawurlencode ()) en ce que pour des raisons historiques, les espaces sont codés sous forme de signes plus (+).

rawurlencode () :

Renvoie une chaîne dans laquelle tous les caractères non alphanumériques à l'exception de -_. ont été remplacés par un signe de pourcentage (%) suivi de deux chiffres hexadécimaux. Il s'agit du codage décrit dans »RFC 1738 pour protéger les caractères littéraux d'être interprétés comme des délimiteurs d'URL spéciaux, et pour empêcher les URL d'être altérées par les supports de transmission avec des conversions de caractères (comme certains systèmes de messagerie).

Les deux sont très similaires, mais le dernier (rawurlencode) remplacera les espaces par un '%' et deux chiffres hexadécimaux, ce qui convient pour coder des mots de passe ou autres, où un '+' n'est pas par exemple:

echo '<a href="ftp://user:', rawurlencode('foo @+%/'),
     '@ftp.example.com/x.txt">';
//Outputs <a href="ftp://user:foo%20%40%2B%25%[email protected]/x.txt">
karim79
la source
2
Le PO demande comment savoir lequel utiliser et quand. Savoir ce que chacun fait avec les espaces n'aide pas le PO à prendre une décision s'il ne connaît pas l'importance des différentes valeurs de retour.
dotancohen
5

1. Quelles sont exactement les différences et

La seule différence réside dans le traitement des espaces:

urlencode - basé sur une implémentation héritée convertit les espaces en +

rawurlencode - basé sur RFC 1738 traduit les espaces en% 20

La raison de la différence est que + est réservé et valide (non codé) dans les URL.

2. lequel est préféré?

J'aimerais vraiment voir quelques raisons de choisir l'une plutôt que l'autre ... Je veux pouvoir en choisir une et l'utiliser à tout jamais avec le moins d'agitation possible.

Assez juste, j'ai une stratégie simple que je suis en train de prendre ces décisions que je partagerai avec vous dans l'espoir que cela puisse aider.

Je pense que c'était la spécification HTTP / 1.1 RFC 2616 qui appelait à des " applications tolérantes "

Les clients DEVRAIENT être tolérants lors de l'analyse de la ligne d'état et les serveurs tolérants lors de l'analyse de la ligne de demande.

Face à de telles questions, la meilleure stratégie consiste toujours à consommer autant que possible et à produire ce qui est conforme aux normes.

Donc, mon conseil est d'utiliser rawurlencodepour produire des chaînes encodées conformes aux normes RFC 1738 et d'utiliser urldecodepour être rétrocompatible et accueillir tout ce que vous pourriez rencontrer.

Maintenant, vous pouvez simplement me croire sur parole, mais prouvons que nous le ferons ...

php > $url = <<<'EOD'
<<< > "Which, % of Alice's tasks saw $s @ earnings?"
<<< > EOD;
php > echo $url, PHP_EOL;
"Which, % of Alice's tasks saw $s @ earnings?"
php > echo urlencode($url), PHP_EOL;
%22Which%2C+%25+of+Alice%27s+tasks+saw+%24s+%40+earnings%3F%22
php > echo rawurlencode($url), PHP_EOL;
%22Which%2C%20%25%20of%20Alice%27s%20tasks%20saw%20%24s%20%40%20earnings%3F%22
php > echo rawurldecode(urlencode($url)), PHP_EOL;
"Which,+%+of+Alice's+tasks+saw+$s+@+earnings?"
php > // oops that's not right???
php > echo urldecode(rawurlencode($url)), PHP_EOL;
"Which, % of Alice's tasks saw $s @ earnings?"
php > // now that's more like it

Il semblerait que PHP ait exactement cela à l'esprit, même si je n'ai jamais rencontré personne refusant l'un des deux formats, je ne peux pas penser à une meilleure stratégie à adopter comme stratégie de facto, n'est-ce pas?

nJoy!

nickl-
la source
4

urlencode : il diffère du codage »RFC 1738 (voir rawurlencode ()) en ce que pour des raisons historiques, les espaces sont codés sous forme de signes plus (+).

Remus Rusanu
la source
2

Espaces codés comme %20vs.+

La plus grande raison que j'ai vue d'utiliser rawurlencode()dans la plupart des cas est parce que urlencodecode les espaces de texte en tant que +(signes plus) où les rawurlencodecode comme les plus courants %20:

echo urlencode("red shirt");
// red+shirt

echo rawurlencode("red shirt");
// red%20shirt

J'ai spécifiquement vu certains points de terminaison d'API qui acceptent les requêtes de texte codées s'attendre à voir %20un espace et, par conséquent, échouer si un signe plus est utilisé à la place. Évidemment, cela va différer entre les implémentations d'API et votre kilométrage peut varier.

Jake Wilson
la source
1

Je crois que l'urlencode est pour les paramètres de requête, tandis que le rawurlencode est pour les segments de chemin. Cela est principalement dû aux %20segments de chemin vs +aux paramètres de requête. Voir cette réponse qui parle des espaces: quand encoder l'espace en plus (+) ou% 20?

Cependant, %20il fonctionne désormais également dans les paramètres de requête, c'est pourquoi le rawurlencode est toujours plus sûr. Cependant, le signe plus a tendance à être utilisé lorsque l'expérience utilisateur de l'édition et de la lisibilité des paramètres de requête est importante.

Notez que cela signifie rawurldecodene pas décoder +en espaces ( http://au2.php.net/manual/en/function.rawurldecode.php ). C'est pourquoi $ _GET est toujours automatiquement transmis urldecode, ce qui signifie que +et %20sont tous deux décodés en espaces.

Si vous souhaitez que le codage et le décodage soient cohérents entre les entrées et les sorties et que vous avez choisi de toujours utiliser +et non %20pour les paramètres de requête, cela urlencodeconvient pour les paramètres de requête (clé et valeur).

La conclusion est:

Segments de chemin - utilisez toujours rawurlencode / rawurldecode

Paramètres de requête - pour le décodage, utilisez toujours urldecode (fait automatiquement), pour le codage, rawurlencode ou urlencode est correct, choisissez-en un pour être cohérent, en particulier lorsque vous comparez des URL.

CMCDragonkai
la source
0

simple * rawurlencode le chemin - chemin est la partie avant le "?" - les espaces doivent être encodés en tant que% 20 * encoder la chaîne de requête en url - La chaîne de requête est la partie après le "?" -les espaces sont mieux encodés car "+" = rawurlencode est généralement plus compatible

haysam elmasry
la source