Я думал, что у меня есть идеальная схема, использующая данные в кодировке base64 для файлов cookie на страницах посетителей, чтобы идентифицировать посетителя. (На самом деле файлы cookie представляют собой кодированный RC4, повторно обработанный с помощью base64, чтобы получить «безопасный файл cookie». Поскольку в любом браузере нет выводимых символов с помощью Base 64, которые являются недопустимыми для файлов cookie, я был уверен, что это не вызовет проблем. Далее я надеялся проверить cookie из PHP-скрипта через массив $ _COOKIE. Казалось, что все идет хорошо, пока конкретное значение cookie не окажется в кодировке base64 как ...
9xu3EhM5 + 6duW4feCL4aHuxOceo =
Определенно не было проблем с записью или чтением этого значения cookie в моем браузере. Если я создаю его с помощью JavaScript, а затем проверяю его с помощью параметров конфиденциальности браузера, он НЕ поврежден. Если я читаю cookie через javascript и отображаю его в alert () или на консоли, он также НЕ поврежден. Но после «чтения» этого файла cookie из массива PHP $ _COOKIE я получил следующее сообщение:
9xu3EhM5 6duW4feCL4aHuxOceo =
Это PHP 5.6, если это имеет значение. Почему отсутствует символ «+»? И, к сожалению, проблема не ограничивается массивом $ _COOKIE! Даже при написании простой PHP-программы, которая отвечает мне тем, что я отправляю (через GET-запрос), я все еще вижу знак «+» в ответе.
Если это проблема, связанная с кодировкой символов, я не вижу, как это сделать. Даже если я просто вставлю URL-адрес своего PHP-скрипта в адресную строку браузера, где ни одна активная страница не установила кодировку символов, знак «+» теряется по пути к скрипту. И я также проверил, что простой скрипт, который ничего не делает, кроме как отвечает жестко закодированной «не поврежденной» строкой, работает нормально.
Очевидно, что проблема заключается в передаче данных из браузера в PHP. И даже если бы я мог придумать какую-нибудь сумасшедшую схему для компенсации строк, передаваемых вручную (например, с помощью запроса POST), я не вижу способа контролировать то, что PHP-скрипт видит, когда данные извлекаются из массива $ _COOKIE.
Что я могу сделать? Я действительно рассчитывал на то, что скрипт сможет выполнить эту, казалось бы, простую задачу.
--- EDIT ---------------
Хотя я обнаружил, что другие жалуются на пропажу таинственного символа «+» с момента публикации, я не нашел простого решения и решил реализовать свое собственное. Так как я в любом случае выполняю все свои base64 (кодирую и декодирую) из своих скриптов PHP, и так как мой код - единственное место, где эти строки должны быть созданы, сохранены и восстановлены, я решил запустить все закодированные base64 Строки через эту процедуру (ниже), прежде чем использовать его для хранения куки. Аналогично, я передам каждый полученный cookie (например, через массив $ _COOKIE) через него до декодирования Base-64.
// from browser to PHP. substitute troublesome chars with
// other cookie safe chars, or vis-versa.
function fix64($inp) {
$out =$inp;
for($i = 0; $i < strlen($inp); $i++) {
$c = $inp[$i];
switch ($c) {
case '+': $c = '*'; break; // definitly won't transfer!
case '*': $c = '+'; break;
case '=': $c = ':'; break; // = symbol seems like a bad idea
case ':': $c = '='; break;
case '/': $c = '_'; break; // no good for dir name!!!
case '_': $c= '/'; break;
default: continue;
}
$out[$i] = $c;
}
return $out;
}
Я просто заменяю "+" (и я также решил "=") другими символами "cookie", прежде чем возвращать закодированное значение на страницу, для использования в качестве cookie.
EDIT -----
Я немного добавил и изменил вышеприведенное, чтобы также удалить / заменить символ "/", что не является проблемой для массива $ _COOKIE, но это неприятный символ, если, например, вы хотите написать файл или создать каталог с тем же именем, что и cookie.
Обратите внимание, что длина обрабатываемой строки не изменяется. Когда та же самая (или другая страница на сайте) снова запускает мой PHP-скрипт и я восстанавливаю cookie, я могу затем передать его обратно через тот же вызов fix64 (), который я создал, зная, что оттуда я могу декодировать его как обычный base64 .
Я не ответил на свой собственный вопрос, так как надеялся, что будет какая-то простая «официальная» настройка PHP, которую я мог бы вызвать, которая изменит это поведение, и я все еще надеюсь, что такая вещь существует. Но для моего случая и на данный момент это разумный подход, который можно легко изменить, если мне когда-нибудь понадобится.