如何在PHP会话中存储对象?

如何在PHP会话中存储对象?,php,pdo,persistence,pdostatement,Php,Pdo,Persistence,Pdostatement,您好,我想在会话中存储或保存一个对象,使用SessionHandler或arrays$\u session之类的类,我已经看到序列化对象是可能的,我不想丢失该对象实例的方法。。 我已经看到这是可能的,但是我想要存储的对象是由PDOStatement::fetchObject()创建的,尽管实例类是“Users”,但我得到以下错误: PDO异常:无法序列化或取消序列化PDO实例 为什么?它不是PDO实例 对不起,我是西班牙人,英语说得不太好。。 感谢PHP的本机$\u会话会话透明地序列化和取消序列

您好,我想在会话中存储或保存一个对象,使用SessionHandler或arrays$\u session之类的类,我已经看到序列化对象是可能的,我不想丢失该对象实例的方法。。 我已经看到这是可能的,但是我想要存储的对象是由PDOStatement::fetchObject()创建的,尽管实例类是“Users”,但我得到以下错误:

PDO异常:无法序列化或取消序列化PDO实例 为什么?它不是PDO实例

对不起,我是西班牙人,英语说得不太好。。
感谢

PHP的本机
$\u会话
会话透明地序列化和取消序列化支持PHP或的对象。您不需要显式地序列化它们

PHP无法序列化,因为这些是PHP无法控制的某些有状态资源的句柄。这就是为什么不能序列化
PDO
PDOStatement
对象

默认情况下,通过保存所有属性名称和值来序列化对象,通过创建具有相同类的对象(不调用构造函数)并直接设置序列化属性来取消序列化对象。您可以使用
\uuuu sleep
\uuu wakeup
魔术方法或通过实现
可序列化
接口来自定义对象的序列化行为。但不是两者都有!如果使用
实现可序列化
睡眠
唤醒
将被忽略

一个重要的注意事项:当使用对象序列化时,必须在取消序列化之前加载类定义(或者有一个可以加载它的自动加载程序),并且它必须与已序列化对象的类定义匹配。类定义不存储在序列化数据中

例如,假设您具有以下各项:

class Test {
    public $version = 1;
    protected $abc;
    public function setAbc($abc) {
        $this->abc = $abc;
    }
}

$t = new Test();
$t->setAbc(123);
$_SESSION['mytest'] = $t;
现在想象一下,有一天你把
Test
改成这样:

class Test {
    public $version = 2;
    private $def;
    public function setDef ($def) {
        $this->def = $def;
    }
}
现在假设您将
Test
处于版本1时序列化的对象加载到新代码中:

$t = $_SESSION['mytest']; // this was stored yesterday, when Test was version 1

var_dump($t)
您将获得以下信息:

object(Test)#1 (3) {
  ["version"]=>
  int(1)
  ["def":"Test":private]=>
  NULL
  ["abc":protected]=>
  int(123)
}
此外,您不能使用旧方法:

if ($t->version == 1) { // Check for class version
    $t->setAbc(345); // "Fatal error: Call to undefined method Test::setAbc()"
}

显示您是如何尝试序列化它的,从异常情况来看,您似乎是在尝试序列化语句,而不是它的结果。我可以序列化
PDOStatement::fetchObject
的结果。如果对象来自数据库,为什么要在会话中序列化它?再从数据库里拿一次。应该尽可能避免会话。感谢它解决了我的问题,但我有一个新问题,在该类上,我在_构造函数(连接到MySQL)中传递PDO对象,并将一个成员变量设置为PDO对象,但当我取消序列化“容器对象”时,它不会执行_构造函数函数,因此,不会设置PDO对象的成员变量。。我怎样才能解决它?谢谢这在回答中有解释。未执行构造函数,因为对象已还原但未初始化。创建执行所需操作的
\uuu wakeup()
序列化程序接口
取消序列化()
方法,或添加
setPDO()
方法并手动设置PDO对象。但底线是,您不应该序列化包含资源的对象!使用不同的类设计。非常感谢,我喜欢您添加setPDO方法的想法,您是对的:)