Some classes aren't supposed to be serialized. Currently, while PHP internal classes have a nice way of preventing being serialized/unserialized, userspace doesn't. I'm proposing to make them equal.
Compare the internals simply slapping ce_flags |= ZEND_ACC_NOT_SERIALIZABLE
to userspace having to do something like this:
class MyClass { public function __sleep() // Wait, what its signature is supposed to be? Does it matter? { throw new Exception('This class must not be serialized'); } public function __wakeup() { throw new Exception('This class must not be unserialized'); } }
Not only is this method bulky, it's also less readable. It also lacks a way to indicate the intention to various code analysers so that they could detect attempts to serialize such classes.
As of the time I'm writing this, there are 94 uses of @not-serializable
in php-src. Examples include:
PDO
, etc.What could userspace use this for?
Introduce a new attribute that would expose this functionality to userspace.
#[NotSerializable] class MyClass { } serialize(new MyClass()); // Exception: Serialization of 'MyClass' is not allowed
The non-serializable flag is inherited by descendants:
class MyOtherClass extends MyClass { } serialize(new MyOtherClass()); // Exception: Serialization of 'MyOtherClass' is not allowed
The above requires no changes to the engine whatsoever, all functionality is already present - it merely gets exposed to userspace.
This feature will be exposed to reflection by the following additions to ReflectionClass:
public const int IS_NOT_SERIALIZABLE = ZEND_ACC_NOT_SERIALIZABLE; public function isSerializable(): bool {}
The only breaking change is the addition of a new non-namespaced class.
8.4.
Make sure there are no open issues when the vote starts!
Implement this RFC? (Yes/no, 2/3 approval required.)
* Proposed PR: https://github.com/php/php-src/pull/12788
After the project is implemented, this section should contain
Keep this updated with features that were discussed on the mail lists.