Some objects don't make sense outside the running process, like services or open resource handles. PHP already blocks serialization of some built-in types, such as closures. This RFC from Dmytro Kulyk lets you do the same for your own classes with a single attribute, #[\NotSerializable].

Before and after

Today, projects fake it by throwing an exception from __serialize() or __sleep(), or by using the old Serializable interface. With this RFC, you add the attribute instead:

#[NotSerializable]
final class TokenBucket {
    public function __construct(
        private int $capacity,
        private float $refillRatePerSecond,
    ) {}
}

serialize(new TokenBucket(10, 1.5)); // Exception: Serialization of 'TokenBucket' is not allowed

The engine refuses before it ever calls __sleep(), __serialize() or Serializable. unserialize() also throws if the payload contains one of these objects, with the message "Unserialization of 'ClassName' is not allowed." The existing allowed_classes option still runs first.

Why you'd want it

The RFC gives a few reasons:

  • Security. Attackers can sometimes chain objects together inside serialized data to run code they shouldn't, which is known as a gadget chain. Blocking a class keeps it out of those chains, and it also stops private data from leaking through serialized strings.
  • Clear intent. The attribute tells readers the class isn't meant to be serialized, and PHP enforces it.
  • Less boilerplate. You don't need to write a method whose only job is to throw.

The rules

  • Child classes inherit it and can't opt out.
  • It works on enums.
  • You can't put it on an interface or a trait. That's a compile-time error.
  • You can detect it with ReflectionClass::getAttributes(NotSerializable::class).
  • json_encode() and var_export() aren't affected.

What it means for existing code

You can no longer declare your own class named NotSerializable in the global namespace. The RFC found 28 matches on GitHub, and nearly all of them were in tests.

Where it stands

It's a draft, dated October 14, 2025. It targets PHP 8.6, and there's a pull request with the implementation. The vote section is still the blank template, so there's no vote yet.