Table of Contents

RFC: Withdraw Deprecation of __sleep() and __wakeup(), Add Soft Deprecation in Documentation

Introduction

A recent RFC to deprecate the __sleep() and __wakeup() magic methods in favor of __serialize() and __unserialize() passed by the narrowest possible margin (18–9). During and after the vote, substantial discussion revealed that the migration path is far more complex, costly, and risky than the RFC presented. This follow-up RFC proposes to withdraw the deprecation and instead introduce a soft deprecation in the documentation.

The aim is to:

Background

The original deprecation RFC argued:

Having multiple serialization methods… is confusing and adds unnecessary complexity…
__serialize() / __unserialize() are a straight up improvement over __sleep() / __wakeup().

However:

> “There is no particular pressing need to phase out __sleep() and __wakeup().”

Problems with the Current Deprecation

1. Migration is not drop-in, produces worse code for many users

Example:

class User {
    public function __construct(
        public readonly string $id,
        public readonly string $email,
        public readonly DateTime $createdAt
    ) {}
 
    public function __sleep(): array {
        return ['id', 'email', 'createdAt'];
    }
 
    public function __wakeup(): void {
        $this->validate();
    }
 
    private function validate(): void {
        if (!filter_var($this->email, FILTER_VALIDATE_EMAIL)) {
            throw new InvalidArgumentException('Invalid email');
        }
    }
}

After migration to __serialize() / __unserialize():

public function __serialize(): array {
    return [
        'id' => $this->id,
        'email' => $this->email,
        'createdAt' => $this->createdAt,
    ];
}
 
public function __unserialize(array $data): void {
    $this->validateData($data);
    $this->id = $data['id'];
    $this->email = $data['email'];
    $this->createdAt = $data['createdAt'];
}

2. Complex compatibility handling for inheritance and payload formats

Example using reflection to preserve compatibility:

public function __serialize(): array {
    $data = [];
    foreach ($this->__sleep() as $key) {
        try {
            $r = new \ReflectionProperty($this, $key);
            if ($r->isInitialized($this)) {
                $data[$key] = $r->getValue($this);
            }
        } catch (\ReflectionException) {
            $data[$key] = $this->$key;
        }
    }
    return $data;
}

3. No technical urgency

4. Narrow vote margin suggests incomplete information

Proposal

1. Withdraw the deprecation voted in previously.

2. Introduce a soft deprecation in documentation:

> “This mechanism is maintained for backward compatibility. New code should prefer __serialize() / __unserialize().”

Benefits

Drawbacks

Vote

Yes / No — Withdraw the deprecation and replace it with a documentation-based soft deprecation.