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.

+3


source to share


1 answer


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"
}

      

+3


source







All Articles