rfc:deprecate-incomplete-class-instantiation

PHP RFC: Prevent instantiation and cloning of __PHP_Incomplete_Class

Introduction

This RFC proposes to prevent instantiation and cloning of the internal class __PHP_Incomplete_Class.

__PHP_Incomplete_Class is used as a placeholder when unserialise encounters an object whose original class definition is not available. It represents an incomplete deserialization state and is not intended to be constructed or duplicated directly.

Proposal

The following changes are proposed:

  • Prevent instantiation of __PHP_Incomplete_Class via new
  • Prevent invoking its constructor
  • Prevent cloning of __PHP_Incomplete_Class instances

Attempting to instantiate the class will throw an Error stating that instantiation of __PHP_Incomplete_Class is not allowed.

Attempting to clone an instance will throw an Error indicating that the object is not cloneable. ReflectionClass::isCloneable will report false for this class.

Objects created internally by unserialize when a class definition is missing remain fully supported and unchanged.

Motivation

__PHP_Incomplete_Class models a failure scenario during deserialization. Allowing it to be instantiated or cloned creates an artificial state that does not reflect how incomplete objects arise in practice.

Incomplete objects should only originate from unserialize when the serialized payload references a class that is not loaded. PHP then creates an __PHP_Incomplete_Class instance and stores the original class name for diagnostic purposes.

This change also aligns with existing constraints: extending __PHP_Incomplete_Class is already not possible, and instantiation via reflection based creation paths that would normally bypass constructors is already not possible. Preventing direct construction and cloning completes the model by ensuring incomplete objects can only arise from their intended source.

Backward Incompatible Changes

Code that directly instantiates or clones __PHP_Incomplete_Class will now fail as __PHP_Incomplete_Class is an internal class not intended for direct use. However, any such usage will need to be refactored to create incomplete objects through unserialization or other means that do not involve direct instantiation or cloning.

Examples

Instantiating __PHP_Incomplete_Class directly will now throw an Error:

// Fatal error: Uncaught Error: Instantiation of class __PHP_Incomplete_Class is not allowed
new __PHP_Incomplete_Class();

Cloning an instance of __PHP_Incomplete_Class will now throw an Error:

// Fatal error: Uncaught Error: Trying to clone an uncloneable object of class __PHP_Incomplete_Class
$incomplete = unserialize('O:16:"NonExistentClass":0:{}');
$clone = clone($incomplete);

Tests that previously relied on direct instantiation can create an incomplete object through unserialize of an unknown class name instead:

// This will create an instance of __PHP_Incomplete_Class without directly instantiating it
$incomplete = unserialize('O:16:"NonExistentClass":0:{}');
 
/*
 * object(__PHP_Incomplete_Class)#1 (1) {
 *  ["__PHP_Incomplete_Class_Name"]=>
 *  string(16) "NonExistentClass"
 * }
 */

Proposed PHP Version(s)

This change is proposed for PHP 8.6.

RFC Impact

To existing extensions

No expected impact. __PHP_Incomplete_Class is an internal class and extensions should not rely on constructing or cloning it directly.

To userland code

Only code that explicitly constructs or clones __PHP_Incomplete_Class is affected. Normal serialization and deserialization flows are unaffected.

Performance

No measurable performance impact is expected. The change only adds guards to construction and cloning paths.

Voting Choices

The vote starts on 2026-xx-xx, ends on 2026-xx-xx, and requires 2/3 majority to be accepted.

Prevent instantiation and cloning of __PHP_Incomplete_Class?
Real name Yes No Abstain
Final result: 0 0 0
This poll has been closed.

Patches and Tests

Implementation

After the RFC 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

References

Links to external references, discussions, or RFCs.

Rejected Features

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

Changelog

If there are major changes to the initial proposal, please include a short summary with a date or a link to the mailing list announcement here, as not everyone has access to the wikis' version history.

rfc/deprecate-incomplete-class-instantiation.txt · Last modified: by jkroon