Почему PHP заменяет плюсы на пробелы в $ _COOKIE?

Поэтому из моего понимания PHP и файлов cookie, если я использую setcookie() , я получаю файл cookie, который автоматически кодируется URL. И когда я иду в массив $_COOKIE , я должен вернуть файл cookie, автоматически расшифрованный url. Проблема в том, что, похоже, он расшифровывает cookie дважды, когда я смотрю в $_COOKIE .

Скажем, у меня есть файл cookie, значение которого «Name | ID | Email», например:

Joe|123|my+email@somewhere.com

Это будет кодироваться как:

Джо% 7C123% 7Cmy% 2Bemail% 40somewhere.com

Обратите внимание, что знак плюса закодирован, поэтому теоретически я должен его вернуть, если я его расшифрую. Поскольку это автоматически выполняется в $_COOKIE , я должен вернуть то, с чего я начал. Но вместо этого я возвращаюсь:

Joe | 123 | мой email@somewhere.com

Обратите внимание на место, где раньше был плюс. Это то, что я ожидал бы, если бы я запустил дополнительный urldecode() cookie. Но я не, поэтому я понятия не имею, почему я получаю пространство вместо плюса.

Еще один интересный поворот. Кажется, что обновление на странице дает правильный результат. Любые идеи, почему это так?

FYI, чтобы установить исходный файл cookie, я использую javascript и escape() скрипт для создания закодированной строки. Может ли это быть проблемой от javascript и PHP?

Мысли будут оценены.

Related of "Почему PHP заменяет плюсы на пробелы в $ _COOKIE?"

Стоит отметить, что оба «% 20» и «+» являются действительными кодировками пробельного символа. За статью в Википедии о кодировке URL (выделено мной):

Когда данные, введенные в формы HTML, отправляются, имена и значения полей формы кодируются и отправляются на сервер в сообщении HTTP-запроса с использованием метода GET или POST или, исторически, по электронной почте. Кодировка, используемая по умолчанию, основана на очень ранней версии общих правил кодирования URI, с рядом модификаций, таких как нормализация новой строки и замена пробелов «+» вместо «% 20» . Тип данных MIME, закодированный таким образом, является application / x-www-form-urlencoded, и в настоящее время он определен (все еще очень устаревшим образом) в спецификациях HTML и XForms.

Более конкретно, связанные с PHP и JavaScript, см. Главный ответ на этот вопрос:

Когда закодировать пробел до плюс (+) или% 20?

если вы не хотите автоматически кодировать свой файл cookie, вы можете использовать функцию setrawcookie () так же, как setcookie ()
но с помощью этой функции вы не можете использовать эти символы внутри значения: (,; \ t \ r \ n \ 013 \ 014):

 setrawcookie("NAME","Joe|123|my+email@somewhere.com"); 

вывод в ресурсе – файлы cookie в хром:

 Joe|123|my+email@somewhere.com 

когда вы эхо $ _COOKIE ['NAME']

 Joe|123|my email@somewhere.com 

Но: что я тестирую в php 5.3.13

 setcookie("NAME","Joe|123|my+email@somewhere.com"); 

вывод в ресурсе – файлы cookie в хром:

 Joe%7C123%7Cmy%2Bemail%40somewhere.com 

когда i echo $ _COOKIE ['NAME']:

 Joe|123|my+email@somewhere.com 

теперь: если вы все еще можете с этим setcookie() , вы можете использовать setcookie() а затем использовать rawurldecode () для его декодирования:

  echo rawurldecode($_COOKIE['NAME']) 

Во-первых, PHP всегда будет работать до JavaScript – это серверная сторона, а не клиентская сторона, поэтому cookie, который вы устанавливаете с помощью JavaScript, на самом деле не будет доступен для PHP до тех пор, пока вы не обновите страницу (следовательно, эта проблема).

Следующий JavaScript имеет разные способы кодирования строк; только один будет работать с PHP автоматически.

Так:

 document.cookie = "testuser=" + "Joe|123|my+email@somewhere.com"; // Joe|123|my email@somewhere.com (when decoded by PHP) document.cookie = "testuser=" + escape("Joe|123|my+email@somewhere.com"); // Joe|123|my email@somewhere.com (when decoded by PHP) document.cookie = "testuser=" + encodeURI("Joe|123|my+email@somewhere.com"); // Joe|123|my email@somewhere.com (when decoded by PHP) document.cookie = "testuser=" + encodeURIComponent("Joe|123|my+email@somewhere.com"); // Joe|123|my+email@somewhere.com 

Итак, попробуйте это ради теста (помните, что вам нужно обновить страницу, чтобы увидеть значение cookie):

 <html> <head> <title>Cookie Juggling</title> <script type="text/javascript"> document.cookie = "testuser=" + encodeURIComponent("Joe|123|my+email@somewhere.com"); </script> </head> <body> <div><?php echo !empty($_COOKIE['testuser']) ? $_COOKIE['testuser'] : "Cookie not set yet"; ?></div> </body> </html>