В документации по PHP говорится: «Вы не можете использовать ссылки в переменных сеанса, поскольку нет возможности восстановить ссылку на другую переменную».
Означает ли это, что я не могу иметь такие вещи, как:
session_start(); $user = new User; $user->name = 'blah'; $_SESSION['user'] = $user;
Я попытался сохранить простую строку и объект User в сеансе, строка всегда сохраняется между страницами на страницы или после обновления страницы. Однако пользовательская переменная теряется в $ _SESSION (становится пустой).
Есть идеи?
Изменить: я подтвердил, что session_id одинаково во всех этих страницах / подстраницах, до и после обновления страницы.
Изменить: Как ни странно, после того, как я попытался выполнить сериализацию и неэтериализованный подход ниже, сериализованный пользовательский объект (или строка) в сеансе все еще исчезает!
Edit: наконец, я понял, что это за ошибка, выглядит как-то $ _SESSION ['user'], переписывается какой-то таинственной силой, если я использую любую переменную, отличную от «пользователя», тогда все в порядке. PHP (не менее 5,3, который является используемой версией) автоматически сериализуется и несистемаризуется, когда вы помещаете объект в $ _SESSION.
session_start(); $user = new User(); $user->name = 'blah' $_SESSION['myuser'] = $user;
Вам нужно использовать магические методы __sleep и __wakeup для объектов PHP 5.
Например, в следующем блоке кода:
$obj = new Object(); $_SESSION['obj'] = serialize($obj); $obj = unserialize($_SESSION['obj']);
__sleep вызывается serialize (). Метод sleep возвращает массив значений из объекта, который вы хотите сохранить.
__wakeup вызывается unserialize (). Метод пробуждения должен принимать неэтериализованные значения и инициализировать их в них в объекте.
В вашем примере кода не используются ссылки, о которых шла речь в документации. Это то, что php означает по ссылкам :
$var =& $GLOBALS["var"];
Что касается помещения объектов в сеанс, PHP может хранить объекты в $_SESSION
. См. http://example.preinheimer.com/sessobj.php .
То, что вы видите, является ошибкой в порядке вызовов __sleep
и __destruct
( __destruct
вызывается до __sleep
), а модуль сеанса не может сериализовать объект при выключении. Эта ошибка была открыта 1 сентября 2009 года.
Вы были правы, говоря, что не можете хранить ссылки в сеансах. Переменные, назначающие объект в PHP 5 и выше, делают именно это, присваивая ссылку не obj
Для этого вам понадобится сериализовать объект (реализующий также __sleep в классе) и присвоение строки переменной сеанса
и десериализуя его позже (реализуя также __wake в классе) из переменной сеанса позже.
Это ожидаемое поведение. Хранение ссылки на объект будет работать только в том случае, если местоположение памяти для объекта не изменилось. В протоколе без учета состояния, таком как HTTP, состояние приложения не сохраняется между запросами. Следующий запрос может обрабатываться другим потоком, процессом или другим сервером.
Учитывая присущую безгражданности веб-приложение, удерживание указателя на ячейку памяти бесполезно. Поэтому состояние объекта должно быть разбито на формат хранения, сохранено или передано, а затем восстановлено, когда это необходимо. Этот процесс известен как сериализация .
Вы можете сериализовать весь объект на сеанс (что может быть опасно в зависимости от глубины вашего графа объекта, поскольку ваш объект может содержать ссылки на другие объекты, и они также должны быть сериализованы), или если объект может быть восстановлен запросив базу данных по следующему запросу, вы можете просто занести идентификатор в сеанс.
[РЕДАКТИРОВАТЬ]
JPot отметил, что объекты автоматически сериализуются в $ _SESSION, поэтому явная сериализация не требуется. Я оставлю ответ для потомков, но, очевидно, это не поможет вашей проблеме.
Для безопасной сериализации и несериализации кодируются и декодируются с base64_encode () и base64_decode () соответственно. Ниже я передаю сериализованный объект в сеанс и неэтериализую его на другой странице, чтобы вернуть переменную в состояние объекта.
Страница 1
<?php require $_SERVER['DOCUMENT_ROOT'] .'/classes/RegistrationClass.php'; $registrationData= new RegistrationClass(); $registrationData->setUserRegData(); $reg_serlizer = base64_encode(serialize($registrationData)); //serilize the object to create a string representation $_SESSION['regSession'] = $reg_serlizer; ?>
Страница 2
<?php session_start(); require $_SERVER['DOCUMENT_ROOT'] .'/classes/RegistrationClass.php'; $reg_unserilizeObj = unserialize((base64_decode($_SESSION['regSession']))); $reg_unserilizeObj->firstName; ?>
В этой статье описываются проблемы, с которыми может столкнуться, если вы этого не сделаете. issus с сериализацией / unserialization php