Zend_Session: очистить $_SESSION перед вызовом start
Допустим, веб-приложение хранит объект класса My_Object в сеансе php под именем "myobject". Когда я открываю другое php-приложение, где этот класс не существует, Zend_Session::start() выдает исключение при попытке десериализации My_Object.
Таким образом, мне нужно очистить переменную $_SESSION, чтобы избавиться от "myobject". Но чтобы очистить переменную $_SESSION, мне сначала нужно вызвать session_start(), и после ее вызова Zend_Session:: start () выдает следующее исключение:
Uncaught исключение 'Zend_Session_Exception' с сообщением 'сессия уже была запущена session.auto-start или session_start()'
Это выбрасывается, даже если я вызываю session_destroy() перед вызовом Zend_Session::start().
Может ли кто-нибудь помочь мне в этом?
Спасибо заранее,
Эрик.
РЕДАКТИРОВАТЬ: Чтобы добавить разъяснение, вот функция, которую я вызываю на моем плагине инициализатора контроллера:
protected function _initSession() {
try {
session_start();
unset($_SESSION['myobject']);
session_destroy();
Zend_Session::start(); // throws an exception !!!
}
catch (Exception $e) {
echo $e; exit;
}
}
РЕДАКТИРОВАТЬ 2:
Чтобы добавить дополнительные пояснения, вот исключение, выдаваемое Zend_Session:: start (), когда он встречает неизвестный класс:
Предупреждение: include_once(My/Object.php): не удалось открыть поток: нет такого файла или каталога в /usr/local/zend/share/ZendFramework/library/Zend/Loader.php в строке 146
Теперь, когда я написал это, мне интересно, смогу ли я начать сеанс до запуска автозагрузчика Zend...
3 ответа
Хорошо, извините за ответ на мой собственный вопрос, но похоже, что я неправильно понял исключение, выданное Zend_Session. Проблема на самом деле возникла из Zend_Loader, а не из основного сеанса PHP. Дело в том, что я инстанцировал автозагрузчик Zend в index.php, что не очень хорошая идея, поскольку с момента его инстанции Zend_Loader будет пытаться автозагрузить каждый класс, который не был явно включен [РЕДАКТИРОВАТЬ: Чтобы быть более понятным, он будет попробуйте создать экземпляр каждого класса, имя которого начинается с одного из зарегистрированных пространств имен - и в моем коде у меня было пространство имен "My_", зарегистрированное в загрузчике zend...]
Решение довольно простое: создать экземпляр Zend_Loader после Zend:Session::start(). Я просто помещаю инициализацию Zend_Loader в мой загрузчик, после Zend_Session::start(), и все работает безупречно: класс My_Object не сериализуется Zend_Session::start() как stdClass (спасибо drew010 за указание меня в правильном направлении); что является исключением.
Спасибо за помощь ребята.
Какую версию Zend Framework вы используете?
Справочное руководство утверждает это:
Использование сессий с объектами
Если вы планируете сохранять объекты в сеансе PHP, знайте, что они будут "сериализованы для хранения. Таким образом, любой объект, сохраняемый в сеансе PHP, должен быть не сериализован при извлечении из хранилища. Подразумевается, что разработчик должен убедиться, что классы для постоянных объектов должны быть определены до того, как объект будет десериализован из хранилища сеансов. Если класс несериализованного объекта не определен, он становится экземпляром stdClass.
Похоже, что одним из возможных обходных путей было бы включить исходный файл для объекта, который сериализован в сеансе, чтобы он не сталкивался с этой ошибкой. Но в нем также говорится, что если класс не определен, он становится экземпляром stdClass, поэтому, поскольку это не то поведение, которое вы видите, это похоже на ошибку или вы используете более старую версию.
Судя по звукам ошибки, проблема не в том, что объект - это проблема, а в том, как вы запускаете сеанс.
Msgstr "Сеанс Uncaught исключения" Zend_Session_Exception "с сообщением" уже запущен session.auto-start или session_start();"
protected function _initSession() {
try {
**session_start();**
unset($_SESSION['myobject']);
session_destroy();
**Zend_Session::start();** // throws an exception !!!
}
catch (Exception $e) {
echo $e; exit;
}
}
В этом коде вы вызываете session_start()
, а затем с помощью Zend_Session::start()
,
Это подразумевает, что сеанс Zend вызывает исключение, если сеансы уже были вызваны ранее.
Вы могли бы просто поймать исключение и просто ничего не делать с ним?
protected function _initSession() {
try {
session_start();
unset($_SESSION['myobject']);
session_destroy();
Zend_Session::start(); // throws an exception !!!
}
catch (Exception $e) {
echo $e; exit;
}
catch (Zend_Session_Exception $zendException)
{
// Do nothing, ignore exception
}
}