Skip to content

language: document the PHP 8.4 comparison and readonly clone BC breaks - #5775

Merged
lacatoire merged 2 commits into
php:masterfrom
lacatoire:language-8.4-bc
Aug 21, 2026
Merged

language: document the PHP 8.4 comparison and readonly clone BC breaks#5775
lacatoire merged 2 commits into
php:masterfrom
lacatoire:language-8.4-bc

Conversation

@lacatoire

@lacatoire lacatoire commented Aug 19, 2026

Copy link
Copy Markdown
Member

Documents the two remaining PHP 8.4 core language BC breaks:

  • Indirect modification of a readonly property within __clone() is no longer allowed, for example acquiring a reference to it. Added as a note to the readonly properties section, right after the PHP 8.3 clone reinitialization paragraph.
  • Encountering recursion during comparison now throws an Error instead of raising a fatal error. Added as a note to the comparison operators page.

Tracker: both items are on the PHP 8.4 Documentation Tracker, listed as "(BC Break) Indirect Modification of readonly Properties" and "(BC Break) Recursion during comparison".

Sources:

  • Indirect modification of readonly properties within __clone(): UPGRADING for PHP 8.4, php-src #15012 (commit 46ee0fb), test Zend/tests/readonly_props/readonly_clone_error7.phpt.
  • Recursion during comparison: UPGRADING for PHP 8.4, php-src #14989 (commit 82479e8), implementation in Zend/zend_hash.c and Zend/zend_object_handlers.c, test Zend/tests/recursive_array_comparison.phpt.

Verified on php:8.3-cli and php:8.4-cli:

class A {
    public readonly array $p;
    public function __construct(array $p) { $this->p = $p; }
    public function __clone(): void { $r = &$this->p; $r[] = 1; }
}
clone new A([0]);
// 8.3: succeeds, the property is modified
// 8.4: Error: Cannot indirectly modify readonly property A::$p

$a = [&$a];
var_dump($a === [[]]);
// 8.3: Fatal error: Nesting level too deep - recursive dependency?
// 8.4: Error: Nesting level too deep - recursive dependency? (catchable)

The comparison note deliberately says "encountering recursion during comparison" rather than referring to a maximum nesting level: the check is a recursion guard, and a single self-referencing value compared against a plain one is enough to trigger it. Comparing a value with itself ($a === $a) still returns true.

@kamil-tekiela kamil-tekiela left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment thread language/operators/comparison.xml Outdated
@lacatoire lacatoire added the 8.4 label Aug 20, 2026
@lacatoire lacatoire added this to the PHP 8.4 milestone Aug 20, 2026
@lacatoire
lacatoire merged commit 62e61e5 into php:master Aug 21, 2026
2 checks passed
@lacatoire
lacatoire deleted the language-8.4-bc branch August 21, 2026 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants