Расширенное использованиеХотя базовое использование является совершенно допустимым вариантом использования сессий Zend Framework, стоит рассмотреть другие возможности их использования. В этой секции обсуждаются тонкости работы с сессиями и показывается более продвинутое использование компонента Zend_Session. Запуск сессииЕсли вы хотите, чтобы все запросы использовали сессии через Zend_Session, тогда запускайте сессию в файле инициализации (bootstrap): Example #1 Запуск глобальной сессии
Запуская сессию в файле инициализации, вы исключаете вероятность её запуска после отправки заголовков браузеру, генерации исключения и возможного отображения испорченой страницы посетителю сайта. Некоторые расширенные возможности так же требуют вызова Zend_Session::start() до начала их использования (Подробнее о расширенных возможностях будет написано позднее.) Существует четыре способа запустить сессию, используя Zend_Session. Два из них - неправильные.
Блокировка пространств имен сессииМожно применять блокировку к пространству имен для предотвращения изменения данных в нем. Используйте метод lock() для того, чтобы сделать определенное пространство имен доступным только для чтения, unLock() - чтобы сделать пространство имен доступным для чтения и изменений, а isLocked() - для проверки, не было ли пространство имен заблокировано ранее. Блокировка не сохраняется от запроса к запросу, не действует на методы установки(setter methods) в объектах, сохраненных в этом пространстве имен, но предотвращает использование методов установки для замены или удаления объектов, сохраненных непосредственно в пространстве имен. Аналогично, блокировка экземпляра Zend_Session_Namespace не препятствует использованию ссылок на те же данные (смотри » PHP references). Example #2 Блокировка пространства имен сессии
Время жизни пространства именВремя жизни может быть ограничено как у пространства имен в целом, так и у отдельных ключей. Общие случаи использованию включают в себя передачу временной информации между запросами и повышение защищенности от определенных угроз безопасности посредством удаления доступа к потенциально чувствительной информации по прошествии некоторого времени после аутентификации. Устаревание может быть основано на количестве секунд или на концепции "прыжков" (hops), в которой "прыжок" происходит при каждом успешном запросе. Example #3 Примеры установки времени жизни
При работе с данными, время жизни которых истекает в текущем запросе, будьте внимательны при их извлечении. Несмотря на то, что данные возвращаются по ссылке, изменение этих данных не приведет к их сохранению после текущего запроса. Для сброса истечения времени жизни, извлеките данные во временные переменные, уничтожьте эти данные в пространстве имен и затем установите соответствующий ключ снова. Инкапсуляция сессий и контроллерыПространство имен может быть использовано для разделения доступа контроллеров к сессии, для защиты переменных от повреждения. К примеру, контроллер аутентификации может хранить свои данные в сессии отдельно от всех остальных контроллеров для достижения требований безопасности. Example #4 Пространства имен сессий с автоматическим устареванием для контроллеров Следующий код, как часть контроллера, отображающего вопрос в тесте, создает переменную с булевым значением для обозначения, должен ли быть принят ответ на вопрос теста. В данном случае пользователю приложения дается 300 секунд на ответ для отображаемого вопроса.
Ниже показан контроллер, обрабатывающий ответы на вопросы теста. Он определяет, принимать ли ответ, на основе того, был ли он отправлен в отведенное время:
Ограничение количества экземпляров на каждое пространство именХотя блокировка сессии предоставляет неплохой уровень защиты против непреднамеренного использования данных сессии в кокретном пространстве имен, Zend_Session_Namespace так же предоставляет возможность предотвратить создание множества экземпляров для одного пространства имен. Для включения этой возможности, передайте TRUE вторым аргументом конструктора при создании последнего разрешенного экземпляра Zend_Session_Namespace. Любая последующая попытка инстанциации этого пространства имен сгенерирует исключение. Example #5 Ограничение доступа к пространству имен сессии одним экземпляром
Второй параметр в конструкторе выше говорит Zend_Session_Namespace, что любые новые экземпляры с пространством имен "Zend_Auth" не разрешены. Попытка создания такого экземпляра вызовет генерацию исключения конструктором. Разработчик сам отвечает за хранение ссылки на экземпляры объектов($authSpaceAccessor1, $authSpaceAccessor2, или $authSpaceAccessor3 в примере выше), если в дальнейшем при обработке того же запроса необходим доступ к этому пространству имен сессии. Например, вы можете сохранять экземпляр в статической переменной или передавать его » реестру (смотри Zend_Registry), или передавать его другим методам, которым нужен доступ к данному пространству имен. Работа с массивамиВсвязи с историей реализаций магических методов в PHP, изменение массивов внутри пространства имен может не работать при версиях PHP меньше 5.2.1. Если вы будете работать только с версиями PHP 5.2.1 или более поздними, тогда вы можете перейти к следующей секции. Example #6 Изменение данных массивов с помощью Zend_Session_Namespace Далее показано, как эта проблема может быть воспроизведена: Example #7 Формирование массива до сохранения в сессию Если возможно, всецело избегайте данной проблемы, сохраняя массивы в пространство имен сессии только после того, как все необходимые значения были установлены.
Если вы используете подверженную проблеме версию PHP и необходимо изменить массив после его сохранения в пространстве имен сессии, вы можете использовать оба или один из следующих обходных путей: Example #8 Обходной путь: Пересохранение измененного массива В последующем коде создается копия сохраненного массива, изменяется и сохраняется обратно, перезаписывая оригинал.
Example #9 Обходной путь: Сохранение массива, содержащего ссылку В качестве альтернативы, сохраниение массива, содержащего ссылку на интересующий массив, с его последующим непрямым изменением: Использование сессии с объектами
Если вы планируете хранить объекты в PHP сессии, имейте в виду, что
они будут » сериализованы
для сохранения. Таким образом, любые объекты, сохраненные в PHP
сессии, должны быть десериализованы при извлечении из хранилища. Подразумевается что
разработчик должен обеспечить определение классов для сохраненных объектов до
десериализации объекта из сессионного хранилища. Если класс десериализуемого объекта
не определен, он становится экземпляром Использование сессии с юнит тестамиZend Framework опирается на PHPUnit для облегчения своего тестирования. Многие разработчики расширяют существующий набор юнит тестов для покрытия кода в их приложении. Если во время выполнения юнит тестирования после закрытия сессии происходит попытка использования пишущих в сессию методов, генерируется исключение "Zend_Session is currently marked as read-only (Zend_Session в данный момент помечен как только для чтения)". Однако Zend_Session требует особое внимание, так как закрытие ( Zend_Session::writeClose()), или уничтожение ( Zend_Session::destroy()) сессии предотвращает дальнейшую установку или удаление ключей в любом экземпляре Zend_Session_Namespace. Это поведение - прямой результат используемого механизма ext/session, методов session_destroy() и session_write_close() в PHP, которые не имеют механизма "отменить" для выполнения настройки/сброса юнит теста.
Для обхода этой проблемы, смотри метод
testSetExpirationSeconds() юнит тестов в
Example #10 PHPUnit тестирование кода, зависимого от Zend_Session
|