Я хочу поговорить не про прикольные флешки на страницах, а про особый вид сессионных переменных. Тема здесь ещё не копалась, если не считать простого упоминания. Кто не в курсе — это read-once данные. Через них, например, удобно передавать текст сообщения со страницы на страницу. Причем между присвоением флеш-переменной значения и её прочтением могут быть промежуточные редиректы, нас это не волнует. Но стоит прочитать переменную, она удаляется.
"Ваш пароль успешно изменён" или
"Вы забыли указать ваш пол"
Прочитал и забыл.
Для красоты я реализовал flashvars через интерфейс ArrayAccess, т.е. обращение выглядит как к массиву.
echo $flash['alpha'];
// всё, этой переменной уже не будет УЖЕ В СЛЕДУЮЩЕМ ЗАПРОСЕ
$flash['beta'] = 9000;
echo $flash['beta'];
// я присвоил, значит переменная сохранится, пока её не прочтут В СЛЕДУЮЩЕМ ИЛИ В 25-м ДРУГОМ ЗАПРОСЕ
Фактически все flash-vars будут хранятся в сессии в специально отведённом разделе.
Особенности реализации: я слегка повернут на паттерне Реестр, поэтому оформил всё через него. И вообще все сессионные переменные через Реестр.
class Registry
{
public static $session;
public static $flash;
}
Если я захочу переделать back-end сессии например на Redis, я просто инициирую $session новым ArrayAccess классом, а класс для $flash останется без изменений.
Скриншоты с тестового приложения:

обработчик:
С точки зрения вызывающей стороны я сохраняю/читаю одинаково и простые сессионные данные, и флешвары.
if (empty($_POST['is_flash'])) {
$ref =& Registry::$session;
} else {
$ref =& Registry::$flash;
}
if (isset($_POST['set'])) {
$ref[$name] = $value;
}
if (isset($_POST['get'])) {
if (isset($ref[$name])) {
$value = $ref[$name];
echo '<p>' . $name . ' = "' . htmlspecialchars($value) . '"</p>';
} else {
echo '<p>' . $name . ' is not set</p>';
}
echo '<p><a href="' . $_SERVER['PHP_SELF'] . '">Click to continue</a></p>';
exit;
}
if (isset($_POST['del'])) {
unset($ref[$name]);
}
header('Location: ' . $_SERVER['PHP_SELF']);
exit();
Но класс, изображающий из себя массив $flash[], помечает те переменные, которые я читаю, на удаление.
public function offsetGet($offset)
{
if (!isset($this->_access[$offset])) {
$this->_access[$offset] = 1; // mark to delete
}
return isset(Registry::$session[$this->_root][$offset]) ? Registry::$session[$this->_root][$offset] : NULL;
}
… и в конце концов, если я не записал поверх новое значение, оно удалится
public function __destruct()
{
foreach ($this->_access as $key => $val) {
if ($val) {
unset(Registry::$session[$this->_root][$key]);
}
}
}
Налетай!