ФорумПрограммированиеPHP для идиотов → Flash Vars & Custom ArrayAccess object

Flash Vars & Custom ArrayAccess object

  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 5 октября 2010 г. 11:21, спустя 1 минуту 12 секунд

    Warning: Этот пост не для идиотов.

    Я хочу поговорить не про прикольные флешки на страницах, а про особый вид сессионных переменных. Тема здесь ещё не копалась, если не считать простого упоминания. Кто не в курсе — это 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]);
               }
           }
       }


    Налетай!
    ιιlllιlllι унц-унц
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 5 октября 2010 г. 11:05, спустя 23 часа 43 минуты 57 секунд

    вопрос на засыпку тебе, о великому велосипедисту всех времен и народов!

    у тебя получается что стираются они только при диструкторе, я бы их стирал реальни при readonce, а то я вот например ленивый и мне придут данные из сессии(с пролйо страницы), и я добавлю чтото, а шаблонизатор дура дважды будет при рендеринге лаоута вызывать нечто типа Response::printMessages которая делает как раз foreach, в итоге я получу больше 1го раза одно сообщение.

    я написал в стиле рыбы используя всякие модные типослова, если не поймешь - скажи напишу по русски :D
    Спустя 38 сек.
    работая в данный момент с флешем и прочитав FlashVars о ттебя, прихуел - думал ты тоже за флеш взялся))) там это типа $_REQUEST :D
    Сапожник без сапог
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 5 октября 2010 г. 11:15, спустя 9 минут 56 секунд

    (request #1) Вверху дебуг-инфа чего есть в нашей сессии.



    вводим имя, отмечаем галочку и кликаем "Get"

    (request #2) надо же! получилось


    (request #3) и где теперь она?


    Шайтан!
    ιιlllιlllι унц-унц
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 5 октября 2010 г. 11:10, спустя 23 часа 54 минуты 44 секунды

    artoodetoo, ты меня не понял. перечитай понтотекст!
    Сапожник без сапог
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 5 октября 2010 г. 11:13, спустя 3 минуты 44 секунды


    у тебя получается что стираются они только при диструкторе, я бы их стирал реальни при readonce, а то я вот например ленивый и мне придут данные из сессии(с пролйо страницы), и я добавлю чтото, а шаблонизатор дура дважды будет при рендеринге лаоута вызывать нечто типа Response::printMessages которая делает как раз foreach, в итоге я получу больше 1го раза одно сообщение.


    Ну испортить можно всё, если постараться. Стирать сразу нельзя, ящитаю! Вдруг мне реально НАДО прочитать несколько раз. Внутри одного реквеста переменная должна выглядеть как простая переменная!!!! А при следующем реквесте её не будет. Фокус-покус.
    Спустя 77 сек.
    я просто не успел прочитать в прошлый раз. Отключил недавалку нахуй. Потому что она мне мешала.
    ιιlllιlllι унц-унц
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 5 октября 2010 г. 11:14, спустя 21 секунду

    А при следующем реквесте её не будет. Фокус-покус.

    ну значит я про flashflash vars jdjh.)))))
    Сапожник без сапог
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 5 октября 2010 г. 11:19, спустя 5 минут 13 секунд

    я пришел именно к такому решению и оно правильное )))
    помоему это грамотный ООП.
    * класс флеш-варов не знает о способе хранения сессий
    * там где читают и пишут флеш-вары, не знают что это не простой массив
    * шайтан-машина просто управляет жизненным циклом переменных, когда надо - сохраняет, когда надо убивает.

    ιιlllιlllι унц-унц
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 5 октября 2010 г. 11:20, спустя 53 секунды

    я пришел именно к такому решению и оно правильное ))

    вынеси очистку в публичный метод, и юзай его в деструкторе. так ты и мне отсосешь и себе так сказать :D
    Сапожник без сапог
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 5 октября 2010 г. 11:23, спустя 3 минуты 1 секунду

    отсоси себе сам ))) но я считаю тебе не следует этого делать
    ιιlllιlllι унц-унц
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 5 октября 2010 г. 11:24, спустя 43 секунды

    artoodetoo, это было завуалированное "удовлетворить потребности"
    Сапожник без сапог
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 5 октября 2010 г. 11:27, спустя 3 минуты 3 секунды

    я понял. просто я пишу для собственного удовлетворения, вот не вижу смысла добавлят лишние возможности. это развращает
    ιιlllιlllι унц-унц
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 5 октября 2010 г. 11:28, спустя 54 секунды

    artoodetoo, да ну тебя)) пошел флеш ковырять)
    Сапожник без сапог
  • Абырвалг

    Сообщения: 6480 Репутация: N Группа: Джедаи

    Spritz 5 октября 2010 г. 12:41, спустя 1 час 13 минут 29 секунд

    некоторых сообщений должно быть несколько:
    * ошибка там-то
    * и еще ошибка вот-там-то


    должны ли как-то отличаться геттеры/сеттеры для еденичных сообщений и для множественных? Или мы работаем из расчета, что сообщений всегда может быть много?
  • AlexB

    Сообщения: 4306 Репутация: N Группа: в ухо

    Spritz 5 октября 2010 г. 12:51, спустя 9 минут 56 секунд

    Идея мне понравилась, как-нибудь заюзаю, тогда скажу впечатления … пока +1 для ровного чсета ))))
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 5 октября 2010 г. 13:01, спустя 10 минут 3 секунды

    абырвалг, тебе как всегда хочется посложнее, да? можно так:

    $flash['foo'] = 'bar'
    и так
    $flash['errors'] = array('dskjdskээ', 'аоалоа', 'выдлвыд', 'лвыовыл');
    и даже этак
    $flash[] = $iter->next();

    класс всё стерпит. но абстракция, конечно имеет дырки. вот так
    $flash['errors'][] = 'slksalksal';
    не получится. это не настоящий массив.
    Спустя 29 сек.
    AlexB, спасибо родной!
    ιιlllιlllι унц-унц

Пожалуйста, авторизуйтесь, чтобы написать комментарий!