How to use PDO :: FETCH_SERIALIZE correctly?
I tried to implement a code that uses PDO::FETCH_SERIALIZE
to automatically unserialize a php object from the database.
I checked the documentation and the related php test that looks basically the same as mine:
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);
But it still doesn't initialize it into something that no one expects. The result of running this code is
object(foo)#4 (1) {
["data":"foo":private]=>
object(foo)#5 (1) {
["data":"foo":private]=>
string(15) "My private data"
}
}
whereas the object cannot be expected to be nested. As it should be
object(foo)#2 (1) {
["data":"foo":private]=>
string(15) "My private data"
}
instead.
What am I missing?
UPD 1 :
I just tried to use a real table instead of hardcoded data. He didn't change anything. The current code is written specifically so that anyone can run it without having to create a test database / tables to test it.
UPD 2 :
The alias name does not change anything and can effectively be omitted entirely.
UPD 3 :
I created an error https://bugs.php.net/bug.php?id=68802 , let's see if the php dev team agrees.
source to share
You are ordering the entire object in a manual query.
$stmt = $pdo->prepare('SELECT \'C:3:"foo":23:{s:15:"My private data";}\' foo');
Should be:
$stmt = $pdo->prepare('SELECT \'s:15:"My private data";\' foo');
Just because it does not foo::serialize
return the s:15:"My private data";
entire serialized object, later, the same serialized string is entered into foo::unserialize
, so in your case, $data instanceof foo
instead of a string.
The output is as you expected:
object(foo)#4 (1) {
["data":"foo":private]=>
string(15) "My private data"
}
source to share