rfc:not_serializable

This is an old revision of the document!


PHP RFC: #[NotSerializable]

Introduction

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 for various code analysers to detect attempts to serialize such classes. If course, linters may introduce their own attributes/annotations to catch such mistakes; however various linters

Analysis

As of the time I'm writing this, there are 94 uses of @not-serializable in php-src. Examples include:

  • Closures
  • Various connections like PDO, etc.
  • Reflection

What could userspace use this for?

  • Wrappers for all the above. Imagine a PDO wrapper that creates connections on demand. If the connection hasn't been established yet, its serialization will succeed, which results in unpredictable behavior.
  • Secret information that shouldn't be accidentally exfiltrated by being serialized.
  • Security-sensitive classes that are unsafe to unserialize with arbitrary data.

Proposal

Introduce a new attribute that would expose this functionality to userspace.

#[NotSerializable]
class MyClass
{
}
 
serialize(new MyClass()); // Exception: Serialization of 'MyClass' is not allowed

This change requires no changes to the engine whatsoever, all functionality is already present - it merely gets exposed to userspace.

Backward Incompatible Changes

The only breaking change is the addition of a new non-namespaced class.

Proposed PHP Version(s)

8.4.

Open Issues

Make sure there are no open issues when the vote starts!

Proposed Voting Choices

Implement this RFC? (Yes/no, 2/3 approval required.)

Patches and Tests

Implementation

After the project is implemented, this section should contain

  1. the version(s) it was merged into
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature
  4. a link to the language specification section (if any)

Rejected Features

Keep this updated with features that were discussed on the mail lists.

rfc/not_serializable.1702122871.txt.gz · Last modified: 2023/12/09 11:54 by maxsem