php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #79352 ArrayObject::serialize and ArrayObject::unserialize are no longer overrideable
Submitted: 2020-03-07 09:43 UTC Modified: 2020-03-07 17:59 UTC
From: tarasov dot igor at gmail dot com Assigned:
Status: Open Package: SPL related
PHP Version: 7.4.3 OS: Linux
Private report: No CVE-ID: None
 [2020-03-07 09:43 UTC] tarasov dot igor at gmail dot com
Description:
------------
If you inherit from ArrayObject and then try to override serialize and unserialize methods, you'll notice that starting with PHP 7.4 these are not executed at all. There are no mentions in the documentation describing this change. Sure, there are new __serialize and __unserialize, but this backward-incompatible change and is not described anywhere.

If you create a custom class implementing Serializable interface, you can still override these methods in child classes, no problem there.

Not sure if this change affects only ArrayObject, I suspect there might be other built-in classes that were changed the same way.

Test script:
---------------
class Foo extends \ArrayObject {
    public function serialize() {
        return 'test';
    }
}

echo serialize(new Foo);

Expected result:
----------------
C:3:"Foo":4:{test}

Actual result:
--------------
O:3:"Foo":3:{i:0;i:0;i:1;a:0:{}i:2;a:0:{}}

So, Foo::serialize is never executed. And it's not like the results are ignored, you can even change it's body to die statement and it won't stop there.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-03-07 09:48 UTC] nikic@php.net
-Type: Bug +Type: Documentation Problem
 [2020-03-07 09:48 UTC] nikic@php.net
You need to override __serialize() and __unserialize(). The Serializable implementation only exists to decode payloads from old PHP versions, and will only be used in that case.

Reclassifying as a documentation problem.
 [2020-03-07 11:06 UTC] tarasov dot igor at gmail dot com
So, then shouldn't be ArrayObject::serialize and ArrayObject::unserialize be declared final starting with PHP 7.4?

There is a mention in backward-incompatible changes https://www.php.net/manual/en/migration74.incompatible.php#migration74.incompatible.spl of ArrayObject, but it only states that ArrayObject and some other SPL classes "now support the __serialize() and __unserialize() mechanism in addition to the Serializable interface". This wording doesn't make it feel like there is something backward-incompatible.
 [2020-03-07 17:59 UTC] nikic@php.net
> So, then shouldn't be ArrayObject::serialize and ArrayObject::unserialize be declared final starting with PHP 7.4?

You may with to override both __serialize()/__unserialize() and Serializable if you care about decoding payloads from previous versions, or being compatible with prior PHP versions. If you only care about PHP 7.4, then overriding __unserialize() is sufficient, and you can ignore Serializable completely.

> There is a mention in backward-incompatible changes https://www.php.net/manual/en/migration74.incompatible.php#migration74.incompatible.spl of ArrayObject, but it only states that ArrayObject and some other SPL classes "now support the __serialize() and __unserialize() mechanism in addition to the Serializable interface". This wording doesn't make it feel like there is something backward-incompatible.

Yes, this is indeed missing, thus the doc bug classification :)
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Oct 07 14:01:27 2024 UTC