urlencode против rawurlencode?

Если я хочу создать URL-адрес с помощью переменной, у меня есть два варианта кодирования строки. urlencode() и rawurlencode().

Какие именно различия и что предпочтительнее?


person Gary Willoughby    schedule 15.06.2009    source источник
comment
Я действительно хотел бы увидеть некоторые причины для выбора одного из них (например, проблемы, которые могут возникнуть с одним или другим), я (и я ожидаю, что другие) хочу иметь возможность просто выбрать один и использовать его навсегда с минимум возни, поэтому я назначил награду за этот вопрос.   -  person Kzqai    schedule 03.08.2011
comment
@Tchalvak: Если вы хотите выбрать только один, выберите rawurlencode. Вы редко встретите систему, которая задыхается, когда заданы пробелы, закодированные как %20, в то время как системы, которые задыхаются от пробелов, закодированных как +, более распространены.   -  person Anomie    schedule 04.08.2011


Ответы (11)


Это будет зависеть от вашей цели. Если совместимость с другими системами важна, то похоже, что rawurlencode - это то, что вам нужно. Единственным исключением являются устаревшие системы, которые ожидают, что строка запроса будет следовать стилю кодирования формы пробелов, закодированных как + вместо% 20 (в этом случае вам нужен urlencode).

rawurlencode следует за RFC 1738 до PHP 5.3.0 и RFC 3986 после него (см. http://us2.php.net/manual/en/function.rawurlencode.php)

Возвращает строку, в которой все не буквенно-цифровые символы, кроме -_. ~, Были заменены знаком процента (%), за которым следуют две шестнадцатеричные цифры. Это кодировка, описанная в »RFC 3986 для защиты буквенных символов от интерпретации как специальных разделителей URL-адресов и для защиты URL-адресов от искажения средствами передачи с преобразованием символов (например, в некоторых системах электронной почты).

Примечание относительно RFC 3986 и 1738. rawurlencode до php 5.3 кодировал символ тильды (~) в соответствии с RFC 1738. Однако, начиная с PHP 5.3, rawurlencode следует RFC 3986, который не требует кодирования символов тильды.

urlencode кодирует пробелы как знаки плюса (а не как %20, как в rawurlencode) (см. http://us2.php.net/manual/en/function.urlencode.php)

Возвращает строку, в которой все не буквенно-цифровые символы, кроме -_. были заменены знаком процента (%), за которым следуют две шестнадцатеричные цифры и пробелы, закодированные как знаки плюс (+). Он кодируется так же, как и отправленные данные из формы WWW, то есть так же, как в типе мультимедиа application / x-www-form-urlencoded. Это отличается от кодировки »RFC 3986 (см. Rawurlencode ()) тем, что по историческим причинам пробелы кодируются как знаки плюса (+).

Это соответствует определению application / x-www-form-urlencoded в RFC 1866.

Дополнительная литература:

Вы также можете увидеть обсуждение на http://bytes.com/groups/php/5624-urlencode-vs-rawurlencode.

Также стоит обратить внимание на RFC 2396. RFC 2396 определяет допустимый синтаксис URI. Основная часть, которая нас интересует, взята из 3.4 Query Component:

В компоненте запроса символы ";", "/", "?", ":", "@",
"&", "=", "+", ",", and "$"
зарезервированы.

Как видите, + - это зарезервированный символ в строке запроса, поэтому его необходимо закодировать в соответствии с RFC 3986 (как в rawurlencode).

person Jonathan Fingland    schedule 15.06.2009
comment
rawurlencode. в этом случае используйте стандарт. urlencode сохраняется только для устаревшего использования - person Jonathan Fingland; 15.06.2009
comment
Большое спасибо, вот что я подумал, я просто хотел узнать второе мнение, прежде чем я начну обновлять много кода. - person Gary Willoughby; 15.06.2009
comment
также кажется, что в моем первоначальном анализе я ошибся, что urlencode был устаревшим вариантом. см. мои изменения для получения дополнительной информации - person Jonathan Fingland; 15.06.2009
comment
Я думаю, что это rawurlencode, который кодирует пробелы не как знаки плюса, а как% 20s - person BigName; 20.10.2010
comment
@Jonathan Fingland Привет, Джонатан, я только что заметил, что этот ответ очень популярен при поиске urlencode в Google. Конечно, это технически правильно, но его трудно читать. Как вы думаете, вы бы хотели переформатировать его для ясности, чтобы сделать его более полезным ресурсом для программистов php, приходящих на эту страницу? Я также сам был бы готов переформатировать его для ясности, если вы дадите мне толчок. - person Kzqai; 24.05.2011
comment
На мой взгляд, ответ расплывчатый: пробелы закодированы как + вместо% 20 (в этом случае вам нужен urlencode), и далее: urlencode не кодирует пробелы как знаки плюса. - person Pindatjuh; 03.08.2011
comment
@Pindatjuh: часть, которую вы процитировали Единственным исключением являются устаревшие системы, которые ожидают, что строка запроса будет следовать стилю кодирования формы пробелов, закодированных как + вместо% 20 (в этом случае вам нужен urlencode) означает, что в то время как rawurlencode подходит для большинства ситуаций, некоторые системы ожидают, что пробелы будут закодированы как + (знак плюса). Для таких систем лучшим выбором будет urlencode. - person Jonathan Fingland; 04.08.2011

Доказательство находится в исходном коде PHP.

Я расскажу вам, как самостоятельно узнавать подобные вещи в будущем в любое удобное для вас время. Потерпите меня, будет много исходного кода C, который вы можете просмотреть (я это объясняю). Если вы хотите освежить немного знаний о C, хорошее место для начала - наша вики SO.

Загрузите исходный код (или используйте http://lxr.php.net/, чтобы просмотреть его в Интернете), grep all файлы для имени функции, вы найдете что-то вроде этого:

PHP 5.3.6 (самый последний на момент написания) описывает две функции в их собственном коде C в файле 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);
}

Хорошо, так что здесь другого?

По сути, они обе вызывают две разные внутренние функции соответственно: php_raw_url_encode и php_url_encode.

Так что ищите эти функции!

Давайте посмотрим на 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);
}

И, конечно же, 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;
}

Прежде чем двигаться дальше, хочу немного узнать об этом: EBCDIC - это еще один набор символов, похожий на ASCII, но тотальный конкурент. PHP пытается справиться с обоими. Но в основном это означает, что байт EBCDIC 0x4c - это не L в ASCII, это на самом деле <. Я уверен, что вы видите здесь путаницу.

Обе эти функции управляют EBCDIC, если это определено веб-сервером.

Кроме того, они оба используют массив символов (подумайте о строковом типе) hexchars поиск, чтобы получить некоторые значения, массив описывается как таковой:

/* 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";

Кроме того, функции действительно разные, и я собираюсь объяснить их в ASCII и EBCDIC.

Различия в ASCII:

URLENCODE:

  • Вычисляет длину начала / конца входной строки, выделяет память
  • Проходит цикл while, увеличивается, пока мы не дойдем до конца строки
  • Хватает настоящего персонажа
  • Если символ равен ASCII Char 0x20 (т. Е. «Пробел»), добавьте к выходной строке знак +.
  • Если это не пробел, и он также не буквенно-цифровой (isalnum(c)), а также не является символом _, - или ., тогда мы выводим знак % в позицию 0 массива, выполняем поиск массива до массива hexchars для поиска массива os_toascii (массив из Apache, который переводит char в шестнадцатеричный код) для ключа c (текущий символ), затем мы выполняем побитовый сдвиг вправо на 4, присваиваем это значение символу 1, а позиции 2 присваиваем то же самое поиск, за исключением того, что мы предварительно формируем логическое и проверяем, равно ли значение 15 (0xF), и возвращаем 1 в этом случае или 0 в противном случае. В конце концов, вы получите что-то закодированное.
  • Если он заканчивается, это не пробел, а буквенно-цифровой или один из _-. символов, он выводит именно то, что есть.

RAWURLENCODE:

  • Выделяет память для строки
  • Итерирует по нему на основе длины, указанной в вызове функции (не вычисляется в функции, как с URLENCODE).

Примечание. Многие программисты, вероятно, никогда не видели, чтобы цикл for выполнялся таким образом, это несколько хакерский и не стандартное соглашение, используемое с большинством циклов for, обратите внимание, оно присваивает x и y, проверяет выход при len достигает 0 и увеличивает как x, так и y. Я знаю, это не то, что вы ожидаете, но это правильный код.

  • Назначает текущий символ соответствующей позиции символа в str.
  • Он проверяет, является ли текущий символ буквенно-цифровым или одним из _-. символов, и если это не так, мы выполняем почти то же назначение, что и с URLENCODE, где он выполняет поиск, однако мы увеличиваем по-разному, используя y++, а не to[1], это потому что струны строятся по-разному, но в конце концов достигают одной и той же цели.
  • Когда цикл завершен и длина пропала, он фактически завершает строку, присваивая байт \0.
  • Он возвращает закодированную строку.

Различия:

  • UrlEncode проверяет наличие пробела, присваивает знак +, RawURLEncode - нет.
  • UrlEncode не назначает байт \0 строке, RawUrlEncode делает (это может быть спорным вопросом)
  • Они повторяются по-разному, одна может быть склонна к переполнению неверно сформированными строками, я просто предлагаю это, и я не фактически исследовал.

В основном они повторяются по-разному, один присваивает знак + в случае ASCII 20.

Различия в EBCDIC:

URLENCODE:

  • Та же настройка итерации, что и для ASCII
  • По-прежнему переводит символ "пробел" в знак + . Примечание.Я думаю, это нужно скомпилировать в EBCDIC, иначе вы получите ошибку? Может ли кто-нибудь отредактировать и подтвердить это?
  • Он проверяет, является ли текущий char символом перед 0, за исключением того, что он . или -, OR меньше A, но больше char 9, OR больше Z и меньше, чем a, но не _. ИЛИ больше, чем z (да, EBCDIC немного запутался при работе). Если он совпадает с любым из них, выполните поиск, аналогичный поиску в версии ASCII (это просто не требует поиска в os_toascii).

RAWURLENCODE:

  • Та же настройка итерации, что и для ASCII
  • Такая же проверка, как описано в EBCDIC-версии кодирования URL-адресов, за исключением того, что если оно больше z, оно исключает ~ из кодирования URL-адресов.
  • То же назначение, что и для ASCII RawUrlEncode
  • По-прежнему добавляется \0 байт к строке перед возвратом.

Общее резюме

  • Оба используют одну и ту же таблицу поиска hexchars
  • URIEncode не завершает строку символом \ 0, в отличие от raw.
  • Если вы работаете в EBCDIC, я бы посоветовал использовать RawUrlEncode, поскольку он управляет ~, чего не делает UrlEncode (это проблема, о которой сообщалось). Стоит отметить, что ASCII и EBCDIC 0x20 являются пробелами.
  • Они повторяются по-разному, один может быть быстрее, другой может быть подвержен уязвимостям на основе памяти или строк.
  • URIEncode делает пробел в +, RawUrlEncode делает пробел в %20 с помощью поиска в массиве.

Отказ от ответственности: я не прикасался к C в течение многих лет, и я не смотрел на EBCDIC действительно очень долгое время. Если я где-то ошибаюсь, дайте мне знать.

Предлагаемые реализации

Исходя из всего этого, в большинстве случаев используется rawurlencode. Как вы видите в ответе Джонатана Фингланда, в большинстве случаев придерживайтесь его. Он имеет дело с современной схемой для компонентов URI, где urlencode работает по старинке, где + означает «пробел».

Если вы пытаетесь выполнить преобразование между старым форматом и новым форматом, убедитесь, что ваш код не дает сбоев и не превращает то, что является декодированным знаком +, в пробел путем случайного двойного кодирования или аналогичными сценариями «упс» вокруг этого пробел / 20% / + проблема.

Если вы работаете в более старой системе со старым программным обеспечением, которое не предпочитает новый формат, придерживайтесь urlencode, однако я считаю, что% 20 на самом деле будет обратно совместим, поскольку при старом стандарте% 20 работал, просто не был предпочтительнее. Попробуйте, если вы готовы поиграть, дайте нам знать, как это сработало для вас.

По сути, вам следует придерживаться raw, если только ваша система EBCDIC действительно вас не ненавидит. Большинство программистов никогда не столкнутся с EBCDIC ни в одной системе, выпущенной после 2000, может быть, даже 1990 года (это подталкивает, но все же, на мой взгляд, вероятно).

person Incognito    schedule 09.08.2011
comment
Мне никогда не приходилось беспокоиться о двойном кодировании, в конце концов, я должен знать, что я кодировал, поскольку это я делаю кодирование, как я думал. Поскольку я декодирую все, что получаю, в режиме совместимости, который знает, как обращаться с + для пространства, я также никогда не сталкивался с проблемами, о которых вы пытаетесь здесь предупредить. Я могу понять, глядя на источник, если мы не знаем, что что-то делает, но что именно мы узнали здесь, чего мы уже не знали, просто выполнив обе функции. Я знаю, что я пристрастен, но не могу не думать, что это вышло за борт. Престижность усилий! знак равно - person nickl-; 28.11.2012
comment
+1, для этой части: я считаю, что% 20 на самом деле будет обратно совместимым, так как по старому стандарту% 20 работал, просто не был предпочтительным - person Gras Double; 10.04.2013

echo rawurlencode('http://www.google.com/index.html?id=asd asd');

дает

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

пока

echo urlencode('http://www.google.com/index.html?id=asd asd');

дает

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

Разница в том, что asd%20asd против asd+asd

urlencode отличается от RFC 1738 тем, что пробелы кодируются как + вместо %20

person jitter    schedule 15.06.2009

Одна из практических причин выбрать одно из них - если вы собираетесь использовать результат в другой среде, например, в JavaScript.

В PHP urlencode('test 1') возвращает 'test+1', а rawurlencode('test 1') возвращает 'test%201' в качестве результата.

Но если вам нужно «декодировать» это в JavaScript с помощью функции decodeURI (), тогда decodeURI("test+1") даст вам "test+1", а decodeURI("test%201") даст вам "test 1" в качестве результата.

Другими словами, пробел (""), закодированный с помощью urlencode на плюс ("+") в PHP, не будет должным образом декодирован с помощью decodeURI в JavaScript.

В таких случаях следует использовать функцию PHP rawurlencode.

person Neven Boyanov    schedule 21.12.2011
comment
Это хороший пример, хотя я предпочитаю json_encode и JSON.parse для этой цели. - person Fabrício Matté; 05.02.2013

Я считаю, что пробелы должны быть закодированы как:

  • %20 при использовании внутри компонента пути URL
  • + при использовании внутри компонента строки запроса URL или данных формы (см. 17.13.4 Типы содержимого форм)

В следующем примере показано правильное использование rawurlencode и _ 4_:

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

Вывод:

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

Что произойдет, если вы закодируете компоненты пути и строки запроса наоборот? Для следующего примера:

http://example.com/category/latest+songs/search?q=lady%20gaga
  • Веб-сервер будет искать каталог latest+songs вместо latest songs
  • Параметр строки запроса q будет содержать lady gaga
person Salman A    schedule 23.09.2012
comment
Параметр строки запроса q будет содержать lady gaga Что еще он мог бы содержать в противном случае? Параметр запроса q, похоже, имеет одно и то же значение, переданное в массив $_GET, независимо от использования rawurlencode или urlencode в PHP 5.2+. Хотя urlencode кодируется в формате application/x-www-form-urlencoded, который используется по умолчанию для запросов GET, поэтому я придерживаюсь вашего подхода. +1 - person Fabrício Matté; 05.02.2013
comment
Я хотел уточнить, что и +, и %20 декодируются как пробелы при использовании в строках запроса. - person Salman A; 05.02.2013

1. В чем именно отличия и

Единственная разница в том, как обрабатываются пробелы:

urlencode - на основе устаревшей реализации преобразует пробелы в +

rawurlencode - на основе RFC 1738 переводит пробелы в% 20

Причина разницы в том, что + зарезервирован и действителен (не закодирован) в URL-адресах.

2. что предпочтительнее?

Я действительно хотел бы увидеть несколько причин для выбора одного из них ... Я хочу иметь возможность просто выбрать один и использовать его вечно с наименьшими усилиями.

Честно говоря, у меня есть простая стратегия, которой я придерживаюсь при принятии этих решений, и я поделюсь с вами в надежде, что она может помочь.

Я думаю, это была спецификация HTTP / 1.1 RFC 2616, которая требовала " Терпимые приложения "

Клиенты ДОЛЖНЫ быть терпимыми при анализе строки состояния, а серверы - терпимыми при анализе строки запроса.

Когда вы сталкиваетесь с подобными вопросами, лучшая стратегия - всегда потреблять как можно больше и производить то, что соответствует стандартам.

Поэтому я советую использовать rawurlencode для создания строк в кодировке RFC 1738, соответствующих стандартам, и использовать urldecode для обеспечения обратной совместимости и размещения всего, что вам может понадобиться.

Поверьте мне на слово, но давайте докажем, что ...

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

Похоже, что PHP имел в виду именно это, хотя я никогда не встречал никого, кто отказывался бы от любого из двух форматов, я не могу придумать лучшую стратегию, которую можно было бы принять в качестве своей стратегии де-факто, не так ли?

nJoy!

person nickl-    schedule 28.11.2012

Разница заключается в возвращаемых значениях, то есть:

urlencode ():

Возвращает строку, в которой все не буквенно-цифровые символы, кроме -_. были заменены знаком процента (%), за которым следуют две шестнадцатеричные цифры и пробелы, закодированные как знаки плюс (+). Он кодируется так же, как и отправленные данные из формы WWW, то есть так же, как в типе мультимедиа application / x-www-form-urlencoded. Это отличается от кодировки »RFC 1738 (см. Rawurlencode ()) тем, что по историческим причинам пробелы кодируются как знаки плюса (+).

rawurlencode ():

Возвращает строку, в которой все не буквенно-цифровые символы, кроме -_. были заменены знаком процента (%), за которым следуют две шестнадцатеричные цифры. Это кодировка, описанная в »RFC 1738 для защиты буквенных символов от интерпретации как специальных разделителей URL-адресов и для защиты URL-адресов от искажения средствами передачи с преобразованием символов (например, в некоторых системах электронной почты).

Эти два очень похожи, но последний (rawurlencode) заменит пробелы на '%' и двумя шестнадцатеричными цифрами, что подходит для кодирования паролей или чего-то подобного, где '+' не является, например:

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">
person karim79    schedule 15.06.2009
comment
OP спрашивает, как узнать, что и когда использовать. Знание того, что каждый делает с пробелами, не помогает OP принять решение, если он не знает важности различных возвращаемых значений. - person dotancohen; 28.11.2012

urlencode: отличается от кодировки »RFC 1738 (см. rawurlencode ( )) в том смысле, что по историческим причинам пробелы кодируются как знаки плюс (+).

person Remus Rusanu    schedule 15.06.2009

Пробелы в кодировке %20 vs. +

Самая большая причина, по которой я использовал rawurlencode() в большинстве случаев, заключается в том, что urlencode кодирует текстовые пространства как + (знаки плюс), где rawurlencode кодирует их как часто встречающиеся %20:

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

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

Я специально видел определенные конечные точки API, которые принимают закодированные текстовые запросы, ожидают увидеть %20 в качестве пробела и, как результат, терпят неудачу, если вместо этого используется знак плюса. Очевидно, что это будет отличаться между реализациями API, и ваш опыт может отличаться.

person Jake Wilson    schedule 27.07.2016

Я считаю, что urlencode предназначен для параметров запроса, а rawurlencode - для сегментов пути. В основном это связано с %20 для сегментов пути и + для параметров запроса. См. Этот ответ, в котором говорится о пробелах: Когда кодировать пробел в плюс ( +) или% 20?

Однако %20 теперь работает и с параметрами запроса, поэтому rawurlencode всегда безопаснее. Однако знак плюса обычно используется там, где важны удобство редактирования и удобочитаемость параметров запроса.

Обратите внимание, что это означает, что rawurldecode не декодирует + в пробелы (http://au2.php.net/manual/en/function.rawurldecode.php). Вот почему $ _GET всегда автоматически передается через urldecode, что означает, что + и %20 оба декодируются в пробелы.

Если вы хотите, чтобы кодирование и декодирование между входами и выходами было согласованным, и вы выбрали всегда использовать +, а не %20 для параметров запроса, то urlencode подходит для параметров запроса (ключ и значение).

Вывод такой:

Сегменты пути - всегда используйте rawurlencode / rawurldecode

Параметры запроса - для декодирования всегда используйте urldecode (выполняется автоматически), для кодирования подходят как rawurlencode, так и urlencode, просто выберите один, который будет согласованным, особенно при сравнении URL-адресов.

person CMCDragonkai    schedule 07.02.2014

simple * rawurlencode путь - путь - это часть перед знаком "?" - пробелы должны быть закодированы как% 20 * urlencode строка запроса - Строка запроса - это часть после "?" -пространства лучше кодируются как "+" = rawurlencode обычно более совместим

person haysam elmasry    schedule 14.03.2017