如何正确使用PDO::FETCH_SERIALIZE?
How to use PDO::FETCH_SERIALIZE correctly?
我尝试实现使用 PDO::FETCH_SERIALIZE
自动反序列化数据库中的 php 对象的代码。
我已经检查了文档和 corresponding php test,它看起来与我所拥有的基本相同:
class foo implements Serializable {
private $data;
public function __construct() {
$this->data = "My private data";
}
public function serialize() {
return serialize($this->data);
}
public function unserialize($data) {
$this->data = unserialize($data);
}
public function getData() {
return $this->data;
}
}
$foo = new foo;
$stmt = $pdo->prepare('SELECT \'C:3:"foo":23:{s:15:"My private data";}\' foo');
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_SERIALIZE, 'foo');
$data = $stmt->fetch();
var_dump($data);
但它仍然将其反序列化为不符合预期的东西。这段代码运行ning的结果是
object(foo)#4 (1) {
["data":"foo":private]=>
object(foo)#5 (1) {
["data":"foo":private]=>
string(15) "My private data"
}
}
而人们不会期望对象是嵌套的。应该是
object(foo)#2 (1) {
["data":"foo":private]=>
string(15) "My private data"
}
相反。
我错过了什么?
UPD 1:
我只是尝试使用真实的 table 而不是硬编码数据。它没有任何改变。当前的代码经过精心设计,因此每个人都可以 运行 它而无需创建测试 database/tables 来检查它。
UPD 2:
别名没有任何变化,实际上可以完全省略。
UPD 3:
我创建了一个错误 https://bugs.php.net/bug.php?id=68802,让我们看看 php 开发团队是否接受它。
您正在手工制作的查询中序列化整个对象。
$stmt = $pdo->prepare('SELECT \'C:3:"foo":23:{s:15:"My private data";}\' foo');
应该是:
$stmt = $pdo->prepare('SELECT \'s:15:"My private data";\' foo');
仅仅因为 foo::serialize
returns s:15:"My private data";
而不是整个序列化对象,稍后,相同的序列化字符串被注入 foo::unserialize
,因此在您的情况下,$data instanceof foo
而不是字符串。
如您所料的输出:
object(foo)#4 (1) {
["data":"foo":private]=>
string(15) "My private data"
}
我尝试实现使用 PDO::FETCH_SERIALIZE
自动反序列化数据库中的 php 对象的代码。
我已经检查了文档和 corresponding php test,它看起来与我所拥有的基本相同:
class foo implements Serializable {
private $data;
public function __construct() {
$this->data = "My private data";
}
public function serialize() {
return serialize($this->data);
}
public function unserialize($data) {
$this->data = unserialize($data);
}
public function getData() {
return $this->data;
}
}
$foo = new foo;
$stmt = $pdo->prepare('SELECT \'C:3:"foo":23:{s:15:"My private data";}\' foo');
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_SERIALIZE, 'foo');
$data = $stmt->fetch();
var_dump($data);
但它仍然将其反序列化为不符合预期的东西。这段代码运行ning的结果是
object(foo)#4 (1) {
["data":"foo":private]=>
object(foo)#5 (1) {
["data":"foo":private]=>
string(15) "My private data"
}
}
而人们不会期望对象是嵌套的。应该是
object(foo)#2 (1) {
["data":"foo":private]=>
string(15) "My private data"
}
相反。
我错过了什么?
UPD 1:
我只是尝试使用真实的 table 而不是硬编码数据。它没有任何改变。当前的代码经过精心设计,因此每个人都可以 运行 它而无需创建测试 database/tables 来检查它。
UPD 2:
别名没有任何变化,实际上可以完全省略。
UPD 3:
我创建了一个错误 https://bugs.php.net/bug.php?id=68802,让我们看看 php 开发团队是否接受它。
您正在手工制作的查询中序列化整个对象。
$stmt = $pdo->prepare('SELECT \'C:3:"foo":23:{s:15:"My private data";}\' foo');
应该是:
$stmt = $pdo->prepare('SELECT \'s:15:"My private data";\' foo');
仅仅因为 foo::serialize
returns s:15:"My private data";
而不是整个序列化对象,稍后,相同的序列化字符串被注入 foo::unserialize
,因此在您的情况下,$data instanceof foo
而不是字符串。
如您所料的输出:
object(foo)#4 (1) {
["data":"foo":private]=>
string(15) "My private data"
}