Почему PHP заменяет плюсы на пробелы в $_COOKIE?
Итак, из моего понимания PHP и файлов cookie, если я использую функцию setcookie()
, тогда я получаю файл cookie, который автоматически кодируется URL. И когда я иду в массив $_COOKIE
, я должен вернуть файл cookie, автоматически расшифрованный url. Проблема в том, что, по-видимому, декодирование файла cookie происходит дважды, когда я смотрю $_COOKIE
.
Скажем, у меня есть файл cookie, чье значение "Name | ID | Email", например:
Joe|123|[email protected]
Это будет закодировано как:
Джо% 7C123% 7Cmy% 2Bemail% 40somewhere.com
Обратите внимание, что знак плюса закодирован, поэтому теоретически я должен его вернуть, если я его расшифрую. Поскольку это автоматически выполняется в $_COOKIE
, я должен вернуть то, с чего я начал. Но вместо этого я возвращаюсь:
Joe | 123 | мой [email protected]
Обратите внимание на место, где раньше был плюс. Это то, чего я ожидал бы, если бы я запустил дополнительный urldecode()
в cookie. Но я не, поэтому я понятия не имею, почему я получаю пространство вместо плюса.
Еще один интересный поворот. Кажется, что обновление на странице дает правильный результат. Любые идеи, почему это так?
FYI, чтобы установить исходный файл cookie, я использую javascript и escape()
script для создания закодированной строки. Может ли это быть проблемой между javascript и PHP?
Мысли будут оценены.
Ответы
Ответ 1
Стоит отметить, что оба "%20" и "+" являются действительными кодировками пробельного символа. В статье Wikipedia на кодировка URL (выделено мной):
Когда данные, введенные в HTML-формы, отправляются, форма имена полей и значения кодируются и отправляются на сервер в HTTP запросить сообщение, используя метод GET или POST, или, исторически, по электронной почте. Используемая по умолчанию кодировка основана на очень ранней версии общие правила кодирования URI, с рядом модификаций такие как нормализация новой строки и замена пробелов на "+" вместо "%20" . Данные типа MIME, закодированные таким образом, являются application/x-www-form-urlencoded, и в настоящее время он определен (все еще очень устаревшим образом) в спецификациях HTML и XForms.
Более конкретно, связанный с PHP и JavaScript, см. главный ответ на этот вопрос:
Когда нужно закодировать пробел до плюс (+) или %20?
Ответ 2
Если вы не хотите автоматически кодировать свой файл cookie, вы можете использовать setrawcookie(), как и setcookie()
но с помощью этой функции вы не можете использовать эти символы внутри значения: (,;\t\r\n\013\014):
setrawcookie("NAME","Joe|123|[email protected]");
вывод в ресурсе - файлы cookie в chrome:
Joe|123|[email protected]
когда вы эхо $_COOKIE ['NAME']
Joe|123|my [email protected]
Но:, что я тестирую в php 5.3.13
setcookie("NAME","Joe|123|[email protected]");
вывод в ресурсе - файлы cookie в chrome:
Joe%7C123%7Cmy%2Bemail%40somewhere.com
когда я echo $_COOKIE ['NAME']:
Joe|123|[email protected]
сейчас:, если вы все еще можете с этим справиться, вы можете использовать функцию setcookie()
, а затем использовать rawurldecode() для его декодирования:
echo rawurldecode($_COOKIE['NAME'])
Ответ 3
Во-первых, PHP всегда будет работать до того, как JavaScript - это серверная сторона, а не клиентская, поэтому cookie, который вы установили с помощью JavaScript, на самом деле не будет доступен для PHP до обновления страницы (следовательно, этой проблемы).
Далее JavaScript имеет разные способы кодирования строк; только один будет работать с PHP автоматически.
Итак:
document.cookie = "testuser=" + "Joe|123|[email protected]";
// Joe|123|my [email protected] (when decoded by PHP)
document.cookie = "testuser=" + escape("Joe|123|[email protected]");
// Joe|123|my [email protected] (when decoded by PHP)
document.cookie = "testuser=" + encodeURI("Joe|123|[email protected]");
// Joe|123|my [email protected] (when decoded by PHP)
document.cookie = "testuser=" + encodeURIComponent("Joe|123|[email protected]");
// Joe|123|[email protected]
Итак, попробуйте это ради теста (помните, что вам нужно обновить страницу, чтобы увидеть значение cookie):
<html>
<head>
<title>Cookie Juggling</title>
<script type="text/javascript">
document.cookie = "testuser=" + encodeURIComponent("Joe|123|[email protected]");
</script>
</head>
<body>
<div><?php echo !empty($_COOKIE['testuser']) ? $_COOKIE['testuser'] : "Cookie not set yet"; ?></div>
</body>
</html>