PHP OOP会话对象-序列化反序列化-处理它


PHP OOP Session Object - Serialize UnSerialize - Dealing With it

我构建了一些常见的类对象,它们将常规地隐藏在$_SESSION对象中。我了解到,在向会话添加对象时,有时可以在不序列化的情况下添加对象,但这是不可靠的,所以我先序列化,每次都有效。

我发现下面的内容令人难以置信的乏味/重复和笨拙…就像我必须检查会话中的对象做一些工作,然后记得以正确的方式检查它。有没有一种更好/更有创意的方法,既有效又可重复使用。帮助PHP专家

// Painful Code
$tmpObj = new clsSession;  // Class setup for intellisense to work.
$tmpObj = unserialize($_SESSION['objSession']);  // I assign so i can get intellisense as well.  
$tmpObj //... do some work make some changes some other logic could be lengthy... 
// and then i have to remember to do the following
$_SESSION['objSession'] = serialize($tmpObj);
unset $tmpObj;
/* or better */
$tmpObj = $_SESSION['objSession'];
$tmpObj = unserialize($tmpObj);
$tmpObj //... do some work make some changes some other logic
//and then i have to remember to do the following
$_SESSION['objSession'] = serialize($tmpObj);
unset $tmpObj;

Tim,谢谢你的意见。几年前,我经历过对象和会话的稳定性问题;序列化和非序列化。在会话反序列化期间丢失类定义是常见的。如果一个类定义为undefined, PHP将创建类__PHP_Incomplete_Class的不完整对象。这个退化的对象错过了所有的方法。为避免此错误,必须在开始会话之前包含每个类定义。因此,如果您在开始会话之前实现自动加载程序,您将不会有任何问题。这一解决方案在过去6年多的时间里运行良好。

在被序列化的对象中使用__sleep魔术方法。这只是返回请求之间所需的属性数组,并允许SESSION中的自动序列化对象正确工作。

public function __sleep() {
    return array('these', 'are', 'property', 'identifiers');
}

可以直接将对象存储到会话中,而不需要先对其进行序列化。这是因为在保存会话时自动进行序列化。只需确保自动加载了类定义。如果没有,则必须在希望使用存储会话对象的每个页面上包含类定义。

除非我遗漏了什么,否则您所做的就是序列化两次:

<?php
class Foo{
    public $id;
}
$f = new Foo;
$f->id = 33;
var_dump( serialize($f) ); // Standard storage
var_dump( serialize(serialize($f)) ); // Yours
我能发现的唯一区别是标准的自动反序列化发生在会话加载时(在session_start()上),这通常发生在早期阶段,并且有可能您仍然没有加载类定义。在你的代码中,当你手动调用unserialize()时,会话首先被读取,对象被重新组合。

我建议您检查您的include_once()指令,并确保在session_start()发生之前加载所有所需的类定义。

这是一个非常强制的测试用例:

<?php
session_start();
if( empty($_SESSION) ){
    require_once('./foo.php');
    $f = new Foo;
    $f->id = 33;
    $_SESSION['f'] = $f;
    // object(Foo)#1 (1) { ["id"]=> int(33) } 
}else{
    $f = $_SESSION['f'];
    // object(__PHP_Incomplete_Class)#1 (2) { ["__PHP_Incomplete_Class_Name"]=> string(3) "Foo" ["id"]=> int(33) } 
}
var_dump($f);