問(wèn)題描述
我正在制作一個(gè)多線程 CLI-PHP 應(yīng)用程序,需要序列化 ??PDO 對(duì)象
以在線程內(nèi)部的工作之間傳遞它,并使用魔術(shù)方法將其從睡眠線程中喚醒 __sleep()
和 __wakeup()
.然而,PDO
或 mysqli
擴(kuò)展也不支持它.舊的 mysql_*()
api 做到了這一點(diǎn),但它已被棄用和刪除.
I am making a multi-threaded CLI-PHP application and need to serialize PDO object
to pass it between work inside the thread, and wake it up from a sleeping thread using magic methods __sleep()
and __wakeup()
. However nor the PDO
or mysqli
extension supports it. The old mysql_*()
api did this but it has been deprecated and removed.
<?php
// Application
$link = new PDO('mysql:host=localhost;port=3306;dbname=testdatabase', 'root', '');
$obj = serialize($link);
產(chǎn)生錯(cuò)誤
PHP 致命錯(cuò)誤:未捕獲的異常 'PDOException' 帶有消息 'You無(wú)法序列化或反序列化 PDO 實(shí)例W:workspaceSandboxapplication.php:5 堆棧跟蹤:
PHP Fatal error: Uncaught exception 'PDOException' with message 'You cannot ser ialize or unserialize PDO instances' in W:workspaceSandboxapplication.php:5 Stack trace:
#0 [內(nèi)部函數(shù)]:PDO->__sleep()
#0 [internal function]: PDO->__sleep()
#1 W:workspaceSandboxapplication.php(5): 序列化(Object(PDO))
#1 W:workspaceSandboxapplication.php(5): serialize(Object(PDO))
#2 {main} 在第 5 行的 W:workspaceSandboxapplication.php 中拋出
#2 {main} thrown in W:workspaceSandboxapplication.php on line 5
推薦答案
PDO 對(duì)象包含無(wú)法以序列化格式表示的狀態(tài).例如,PDO 對(duì)象包含一個(gè)到數(shù)據(jù)庫(kù)服務(wù)器的開(kāi)放連接.
A PDO object contains state that cannot be represented in the serialization format. For example, the PDO object contains an open connection to a database server.
如果您嘗試反序列化一個(gè)序列化的 PDO 對(duì)象,__wakeup()
方法必須重新連接到數(shù)據(jù)庫(kù)服務(wù)器.這將要求身份驗(yàn)證憑證以可讀方式存儲(chǔ)在序列化 PDO 對(duì)象中,這是安全禁忌.
If you were to try to deserialize a serialized PDO object, the __wakeup()
method would have to reconnect to the database server. This would require that authentication credentials be stored in a readable manner in the serialized PDO object, which is a security no-no.
我很早以前就在研究 Zend Framework 的 Zend_Db 組件,因此我特意將 Zend_Db_Adapter 對(duì)象設(shè)計(jì)為不可序列化.Zend_Db_Table、Zend_Db_Table_Row 等的實(shí)例可以序列化,但在反序列化后不能活動(dòng)",除非你為它分配了一個(gè)新連接的 Zend_Db_Adapter 實(shí)例.
I worked on the Zend Framework's Zend_Db component a long time ago, and I deliberately designed the Zend_Db_Adapter object to not be serializable for this reason. Instances of Zend_Db_Table, Zend_Db_Table_Row, etc. could be serializable, but could not be "live" after deserialization until you assigned it a freshly connected Zend_Db_Adapter instance.
此外,無(wú)法保證在您反序列化 PDO 對(duì)象時(shí)可以訪問(wèn)數(shù)據(jù)庫(kù)服務(wù)器.目前尚不清楚這是否意味著反序列化將被視為失敗".
Also, there's no guarantee that the database server would be reachable at the time you deserialize the PDO object. It's unclear whether this means the deserialization would be considered "failed."
對(duì)序列化的相同限制適用于其他資源,例如套接字或文件句柄.
The same restrictions on serialization apply to other resources such as sockets or file handles.
另見(jiàn) 為什么不是每種類型的對(duì)象都可序列化?
這篇關(guān)于為什么不能序列化 PDO 對(duì)象?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!