在PHP会话中存储对象

31 php session

PHP文档说"你不能在会话变量中使用引用,因为没有可行的方法来恢复对另一个变量的引用."

这是否意味着我不能拥有以下内容:

session_start();
$user = new User;
$user->name = 'blah';
$_SESSION['user'] = $user;
Run Code Online (Sandbox Code Playgroud)

我试图在会话中存储一个简单的字符串和一个User对象,该字符串始终在页面之间或页面刷新之后持续存在.但是,$ _SESSION中的User变量丢失(变为空).

任何的想法?

编辑:我已确认在页面刷新之前和之后所有这些页面/子页面中的session_id都相同.

编辑:奇怪的是,在我尝试下面的序列化和反序列化方法后,会话中的序列化用户对象(或字符串)仍然消失!

编辑:最后我弄明白了这个bug是什么,看起来好像$ _SESSION ['user']被一些神秘的力量覆盖,如果我使用除'user'之外的任何变量,那么一切都很好.当你将对象放在$ _SESSION中时,PHP(至少5.3这是我正在使用的版本)会自动序列化和反序列化.

session_start();
$user = new User();
$user->name = 'blah'
$_SESSION['myuser'] = $user; 
Run Code Online (Sandbox Code Playgroud)

Noa*_*ich 50

您需要为PHP 5对象使用magic __sleep和__wakeup方法.

例如,在以下代码块中:

$obj = new Object();

$_SESSION['obj'] = serialize($obj);

$obj = unserialize($_SESSION['obj']);
Run Code Online (Sandbox Code Playgroud)

__sleep由serialize()调用.sleep方法将返回要保留的对象的值数组.

__wakeup由unserialize()调用.唤醒方法应该采用未序列化的值并在对象中将它们初始化.

  • 您可以定义它们来覆盖默认的序列化和反序列化机制,例如将相关(引用)对象与主对象一起序列化,然后将它们全部恢复。 (2认同)

gbc*_*gbc 0

这是预期的行为。仅当对象的内存位置未更改时,存储对对象的引用才有效。在 HTTP 等无状态协议中,应用程序状态不会在请求之间保留。下一个请求可能会在另一个线程、进程或另一个服务器上处理。

鉴于 Web 应用程序固有的无状态性质,持有指向内存位置的指针是没有用的。因此,对象的状态必须被分解为存储格式,保存或传输,然后在需要时重构。此过程称为序列化

您可以选择将整个对象序列化到会话中(这可能很危险,具体取决于对象图的深度,因为您的对象可能保存对其他对象的引用,并且这些对象也需要序列化),或者是否可以重构对象通过在下一个请求时查询数据库,您可以在会话中存储一个 ID。

[编辑]

JPot 指出对象会自动序列化为 $_SESSION,因此不需要显式序列化。我会将答案留给后代,但显然这对您的问题没有帮助。