为什么不能将PDO对象序列化?

Jun*_*ior 4 php pdo

我想提出一个多线程的CLI-PHP应用程序和需要序列化PDO object工作之间传递的线程内,并使用魔术方法睡眠线程唤醒它__sleep()__wakeup().然而,PDO或者mysqli扩展不支持它.旧mysql_*()api做了这个,但它已被弃用并删除.

<?php
    // Application
    $link = new PDO('mysql:host=localhost;port=3306;dbname=testdatabase', 'root', '');

    $obj = serialize($link);
Run Code Online (Sandbox Code Playgroud)

很好地产生错误

PHP致命错误:未捕获异常'PDOException',并在W:\ workspace\Sandbox\application.php中显示消息'您无法自定义或反序列化PDO实例':5堆栈跟踪:

#0 [内部函数]:PDO - > __ sleep()

#1 W:\ workspace\Sandbox\application.php(5):serialize(Object(PDO))

在第5行的W:\ workspace\Sandbox\application.php中抛出#2 {main}

Bil*_*win 11

PDO对象包含无法以序​​列化格式表示的状态.例如,PDO对象包含与数据库服务器的开放连接.

如果您尝试反序列化序列化的PDO对象,则该__wakeup()方法必须重新连接到数据库服务器.这将要求身份验证凭证以可读方式存储在序列化PDO对象中,这是一种安全禁忌.

我很久以前就研究过Zend Framework的Zend_Db组件,因此我故意将Zend_Db_Adapter对象设计为不可序列化.Zend_Db_Table,Zend_Db_Table_Row等实例可以序列化,但在反序列化后无法"生效",直到您为其分配了一个新连接的Zend_Db_Adapter实例.

此外,无法保证在反序列化PDO对象时可以访问数据库服务器.目前尚不清楚这是否意味着反序列化将被视为"失败".

序列化的相同限制适用于其他资源,如套接字或文件句柄.

另请参见为什么不是每种类型的对象都可序列化?