Cookie против флэш-сообщения на основе сеанса
Яркой особенностью, которую я нашел в CakePHP, была возможность установить flash
сообщение, скажем, на каком-то скрипте save
, а затем отобразить это сообщение на следующей странице. Что-то вроде, Post updated
или Error - no file found.
То, как Cake делает это с этим объектом session
. Я стараюсь избегать сеансов, таких как чума, из-за их странных требований к масштабируемости. Могу я просто не просто сохранить флэш-сообщение в cookie (на стороне клиента), а затем удалить этот файл cookie после его отображения на следующей странице? Каковы будут некоторые плюсы и минусы этого подхода - или, проще говоря, почему Cake использует session
(я предполагаю, что относится к коллекции _SESSION
).
Ура!
ps В моей реализации я также заставляю ее исчезать с помощью команды setTimeout
в javascript. Я нахожу этот хороший способ закончить весь процесс.
Ответы
Ответ 1
Проблема с файлом cookie заключается в том, что пользователь может отключить эту функцию. Если это так, ваше флеш-сообщение не будет отображаться. CakePHP пытается быть достаточно общим и использует хранилище сеансов.
У вас есть 3 варианта:
- Сеанс: наиболее часто используемый подход. Он будет работать на любом клиентском компьютере, но, как вы говорите, он может вызвать проблемы с некоторыми конфигурациями сервера.
- Cookies: это хороший вариант в целом, но пользователь может заблокировать этот механизм. Рекомендовать только в том случае, если ваши требования к приложению включают в себя куки файлы.
- База данных: универсальное решение. Проблема в том, что он требует доступа к базе данных (медленный). Идентификатор должен быть передан с помощью URL (метод GET), поэтому приложение знает, какой регистр базы данных соответствует этому доступу.
В моих приложениях я использую комбинацию 2-го и 3-го подходов: я тестирую файлы cookie, и если они доступны, я их использую. Если нет, я использую доступ к базе данных, НО я всегда кэширую доступ к БД, чтобы не запрашивать более одного раза для каждого сообщения.
Ответ 2
Я не понимаю, почему вы не можете использовать cookie с истечением 10 минут с даты создания. Вниз, если пользователь уйдет и вернется через 11 минут, они могут не увидеть сообщение флэш файла cookie... но вам не придется беспокоиться о том, чтобы наводнить клиента куки файлами.
Просто сделайте несколько простых правил содержания, чтобы гарантировать, что никакая привилегированная информация не будет помещена во флэш-сообщение, и вы должны быть хорошими.
Простая реализация может быть чем-то процедурным, например:
function setFlash($id ,$message){
setcookie("flash_{$id}", $message, time() + 60 * 10);
}
function getFlashes(){
$flashes = array();
foreach($_COOKIE as $id => $value){
if(strpos($id, "flash_") === 0){
$flashes[$id] = $value;
//clear flash and set expiration to 10 minutes in past
setcookie($id, "", time() * 60 * -10);
}
}
return $flashes;
//Input cleansing not included for brevity/clarity
}
В качестве альтернативы, если флешка происходит со стороны клиента, вы можете использовать что-то вроде https://github.com/marcuswestin/store.js, чтобы попытаться использовать хранилище localSession для управления флэш-сообщения.
Ответ 3
Другая идея - перенос сообщения через хэш в URL:
if (isset($_POST['submit'])) {
...
header("Location: ".$_SERVER["REQUEST_URI"]."#".urlencode($msg));
...
}
Преимущества:
- Работает без файлов cookie/сеансов/баз данных /memcach и т.д.: -)
- Не полагается на часы клиента как файлы cookie
- Ни один другой запрос клиента не может "украсть" сообщение
Неудобство:
Ответ 4
Сессии, к сожалению, не всегда надежны, если за ними следует Header ("Location...");
Я думал о том, чтобы поместить его в запрос GET или тег Hash, как было предложено, и вы можете удалить его на следующей странице, используя javascript из URL-адреса, используя window.history.pushState.
Изменение: если session_write_closed(); используется.