Orm: DDC-3120: Warning: Erroneous data format for unserializing PHP5.6+

Created on 11 May 2014  路  46Comments  路  Source: doctrine/orm

Jira issue originally created by user techkey:

Hi all,

There seems to be something strange going on in the method newInstance() of the class \Doctrine\ORM\Mapping\ClassMetadataInfo.

The original class method looks like this:

{quote}\Doctrine\ORM\Mapping\ClassMetadataInfo#newInstance(){quote}

    {
        if ($this->_prototype === null) {
            $this->_prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name));
        }

        return clone $this->_prototype;
    }

What happens now when a class that implements \Serializable is that a "Warning: Erroneous data format for unserializing" shows up and the function unserialize() returns false.

That is because a class that implements \Serializable is expected to have the letter 'C' in the serialize string instead of the letter 'O'.

I've made a quick work-around like this:

{quote}\Doctrine\ORM\Mapping\ClassMetadataInfo#newInstance(){quote}

    {
        if ($this->_prototype === null) {
            $this->_prototype = @unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name));
            if ($this->_prototype === false) {
                $this->_prototype = unserialize(sprintf('C:%d:"%s":0:{}', strlen($this->name), $this->name));
            }
        }

        return clone $this->_prototype;
    }

That seems to work in my isolated tests and with Symfony2 and Doctrine2 and FOSUserBundle together.

I've noticed this because the Model\User class from FOSUserBundle implements \Serializable.

I had to implement a check in Model\User class because when using {{'C:%d:"%s":0:{}'}} the $serialized parameter of the unserialize method in the Model\User class is a empty string then.

That warning seems only to happen with PHP5.6+. PHP5.5.12 and below doesn't show that warning.

I hope someone can shine some light on this, thank you,

Cornelis.

Bug

Most helpful comment

Hi every one,

I had the same issue with PHP 5.6.16 on a Windows 10 Pro 64 bit install with wamp3 for 64 bits and after making changes to doctrine line in composer.jsonthis way:

"doctrine/orm": "~2.4.6,>=2.2.3,<2.5",

and changing the _C:\wamp64\www\doctors\vendor\doctrine\ormlibDoctrine\ORM\Mapping\ClassMetadataInfo.php_ at line 869 like this:

    public function newInstance()
        {
            if ($this->_prototype === null) {
869            if (PHP_VERSION_ID >= 50513 || PHP_VERSION_ID === 50429 || PHP_VERSION_ID === 50513) {
                    $this->_prototype = $this->reflClass->newInstanceWithoutConstructor();
                } else {
                    $this->_prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name));
                }
            }
            return clone $this->_prototype;
        }

it just worked.
I was using this repository Doctors from @benaich for tutorial purposes when i got into this issue.

I hope this might help.
Regards from Cuba.

All 46 comments

Comment created by @ocramius:

Indeed, for PHP 5.4+ we should use ReflectionClass#newInstanceWithoutConstructor()

Comment created by techkey:

Just tested it. That works as expected, far more better then the dirty hacks I did, thanks a lot!

Any idea when this would be implemented into the code?

Comment created by @ocramius:

Send a pull request and I'll merge it later today (we could also need a failing test with an entity implementing the Serializable interface)

Comment created by evertharmeling:

Seems to be a problem in the latest PHP 5.4 version too.

https://github.com/doctrine/doctrine2/pull/1045/

Comment created by @doctrinebot:

A related Github Pull-Request [GH-1045] was closed:
https://github.com/doctrine/doctrine2/pull/1045

Comment created by rkmax:

I am facing this same error i have PHP 5.5.13, I'm using Symfony, Doctrine ORM and FOSUserBUndle

Comment created by @ocramius:

[~rkmax] the patch landed in master (2.5.x) for now.

Comment created by @ocramius:

Merged via DDC-3147

Comment created by tbuhk:

When can we expect the version with this bugfix?

Comment created by gnuk:

Why don't you tag 2.4.3 version with this fix ? Because the error is already present in PHP 5.5.13 which is a stable version and it's a blocking issue when you're using FOSUserBundle for example. There is also no opened issue refering this version and the due date is in april.

Comment created by j.perovic:

I'm still seeing this bug, although my PHP_VERSION_ID is 50600 :(

So, version based condition is no good...

Comment created by @ocramius:

The approach to be taken for 50600 is still under discussion in php-internals.

Comment created by techkey:

Hi all,

I've just downloaded PHP5.6RC1 and updated doctrine and the error is back indeed.

A little peek at the code starting on line 866 of file Doctrine\ORM\Mapping\ClassMetadataInfo.php shows this:

    public function newInstance()
    {
        if ($this->_prototype === null) {
            if (PHP*VERSION_ID === 50429 || PHP_VERSION*ID === 50513) {
                $this->_prototype = $this->reflClass->newInstanceWithoutConstructor();
            } else {
                $this->_prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name));
            }
        }

        return clone $this->_prototype;
    }

As can be seen, PHP5.6 is out of the picture, it only checks for the exact versions 5.4.29 and 5.5.13.

So for the code to work correctly on PHP5.6 one can add PHP5.6 to the test condition, or just skip the test all together if you don't mind the old PHP5.3. According to PHP, ReflectionClass::newInstanceWithoutConstructor is available since PHP >= 5.4.0.

Greetings, Cornelis.

Comment created by @ocramius:

As I already pointed out, this is still being discussed in php internals. See http://news.php.net/php.internals/75009

This won't be dealt with in 5.6 until there's either a stable release or internals decides what has to be done.

Comment created by @ocramius:

Also, ReflectionClass#newInstanceWithoutConstructor() still doesn't cover the pre-existing "hack" using unserialize, so we're still waiting for a reliable API from PHP core.

Comment created by chasen:

Using PHP 5.6RC2 and ORM 2.4.4 I am still experiencing this issue. I have also tested with PHP 5.5.15 and I am still getting the issue. Do i need to be using a different build of ORM to have the fix applied?

Comment created by pascall:

Hi,
I'm using 5.6.0beta3 and ORM 2.4.4 and i have the same probleme
Warning: Erroneous data format for unserializing .. in orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php line 872

and in current code in ClassMetadataInfo.php line 872 is :

public function newInstance()
{
    if ($this->_prototype === null) {
        if (PHP*VERSION_ID === 50429 || PHP_VERSION*ID === 50513) {
            $this->_prototype = $this->reflClass->newInstanceWithoutConstructor();
        } else {
            $this->_prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name));
        }
    }

    return clone $this->_prototype;
}

Comment created by evertharmeling:

As stated by Marco Pivetta; "This won't be dealt with in 5.6 until there's either a stable release or internals decides what has to be done.". And besides that 5.6 still is in development, not stable.
If you still want to use 5.6 you can fork the code and extend the 5.4 / 5.5 check to support 5.6.

Comment created by chasen:

5.6 has an RC which should mean a stable API, and that only bugs will be fixed before an official stable release?

Comment created by evertharmeling:

Looking at http://news.php.net/php.internals/75966 it's still being discussed, and they are planning to have it fixed in RC3.

Comment created by @ocramius:

Internals still didn't get to a clear decision. Until then, we won't support 5.6 officially.

Comment created by Ronan:

Same error encountered with PHP 5.5.13 (cli) (built: May 30 2014 10:43:29)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2014, by Zend Technologies
with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans

(PHP 5.5 installed via http://php-osx.liip.ch/)

Comment created by @ocramius:

[~Ronan] what D2 version? We fixed it for 2.4.x (temporarily)

Comment created by Ronan:

My bad: reading my composer.lock: doctrine/orm, v2.4.2, ref 0363a5548d9263f979f9ca149decb9cfc66419ab, "time": "2014-02-08 16:35:09"... Well.. this is was an old one !

composer update fixed it. Sorry for disturbing.

Comment created by chasen:

Im still getting this error running php 5.6RC2 and the dev-master(6ac19b04bfbd7a97aad5ed8c2abd6279ff5e0022) build of D2/orm. Am i missing something?

Comment created by @ocramius:

This was semi-fixed in PHP5.6-RC3, and it will be patched into ORM once doctrine/instantiator is out

Comment created by chasen:

Ok good to know. Thanks

Comment created by @ocramius:

Not yet fixed for PHP 5.6

Comment created by @ocramius:

Provided a hotfix proposal at https://github.com/doctrine/doctrine2/pull/1109 - please check it out with PHP 5.6.0-RC3 or later

Comment created by @doctrinebot:

A related Github Pull-Request [GH-1109] was closed:
https://github.com/doctrine/doctrine2/pull/1109

Comment created by @ocramius:

Due to a new introduced dependency, this issue will only be solved for PHP 5.6 in 2.5.0 and later.

Comment created by @doctrinebot:

A related Github Pull-Request [GH-1109] was assigned:
https://github.com/doctrine/doctrine2/pull/1109

Comment created by dominik.[email protected]:

@ocramius would be great if there where backports for 2.4 and 2.3

Comment created by r1pp3rj4ck:

I agree with Dominik, we'd like to use the latest stable version and would need this patch.

Comment created by @ocramius:

This has been backported in DDC-3339

Comment created by sysko:

I still have this error even 2.5.0 and PHP5.6
https://travis-ci.org/allan-simon/oauth2-symfony2-vagrant-fosuserbundle/jobs/62429219

Issue was closed with resolution "Fixed"

Hi every one,

I had the same issue with PHP 5.6.16 on a Windows 10 Pro 64 bit install with wamp3 for 64 bits and after making changes to doctrine line in composer.jsonthis way:

"doctrine/orm": "~2.4.6,>=2.2.3,<2.5",

and changing the _C:\wamp64\www\doctors\vendor\doctrine\ormlibDoctrine\ORM\Mapping\ClassMetadataInfo.php_ at line 869 like this:

    public function newInstance()
        {
            if ($this->_prototype === null) {
869            if (PHP_VERSION_ID >= 50513 || PHP_VERSION_ID === 50429 || PHP_VERSION_ID === 50513) {
                    $this->_prototype = $this->reflClass->newInstanceWithoutConstructor();
                } else {
                    $this->_prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name));
                }
            }
            return clone $this->_prototype;
        }

it just worked.
I was using this repository Doctors from @benaich for tutorial purposes when i got into this issue.

I hope this might help.
Regards from Cuba.

This is handled by doctrine/instantiator in 2.5

So would you recommend me to upgrade to doctrine 2.5 ?

Definitely no possible for me. Look the results:

c:\wamp64\www\doctors>php composer.phar require doctrine/orm:~2.5.4
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Installation request for doctrine/orm ~2.5.4 -> satisfiable by doctrine/orm[v2.5.4].
    - Conclusion: remove doctrine/cache v1.3.0
    - Conclusion: don't install doctrine/cache v1.3.0
    - doctrine/orm v2.5.4 requires doctrine/cache ~1.4 -> satisfiable by doctrine/cache[1.5.3, v1.4.0, v1.4.1, v1.4.2, v1.4.3, v1.4.4, v1.5.0, v1.5.1, v1.5.2, v1.5.4, v1.6.0].
    - Can only install one of: doctrine/cache[1.5.3, v1.3.0].
    - Can only install one of: doctrine/cache[v1.4.0, v1.3.0].
    - Can only install one of: doctrine/cache[v1.4.1, v1.3.0].
    - Can only install one of: doctrine/cache[v1.4.2, v1.3.0].
    - Can only install one of: doctrine/cache[v1.4.3, v1.3.0].
    - Can only install one of: doctrine/cache[v1.4.4, v1.3.0].
    - Can only install one of: doctrine/cache[v1.5.0, v1.3.0].
    - Can only install one of: doctrine/cache[v1.5.1, v1.3.0].
    - Can only install one of: doctrine/cache[v1.5.2, v1.3.0].
    - Can only install one of: doctrine/cache[v1.5.4, v1.3.0].
    - Can only install one of: doctrine/cache[v1.6.0, v1.3.0].
    - Installation request for doctrine/cache (locked at v1.3.0) -> satisfiable by doctrine/cache[v1.3.0].


Installation failed, reverting ./composer.json to its original content.

That is for you to solve, not a bug in ORM :-)

Thanks, i already solved it.That was my original post, the solution. Thanks.

I got the same error with Doctrine 2.5, Symfony 3.1, PHP 5.6, Windows 7 (64x) and 've been dissapointed a bit... How can I solve the issue?

i khow this it an old topic, but i solve it with this
you need khow your php version, can add a var_dump(PHP_VERSION_ID); on app.php
then add your version on line 830 on \www\vendor\doctrine\ormlibDoctrine\ORM\Mapping\ClassMetadataInfo.php file
another think that help is able display php errors

Was this page helpful?
0 / 5 - 0 ratings