Category
language · php-src-strict
Problem
PHP 8.4 asymmetric property visibility (public private(set) int $x) is valid syntax. This compiler rejects it at parse/compile with Multiple access type modifiers are not allowed, blocking PHP 8.4 language parity.
Related runtime gaps (#9842 private(set) write message, #6772 reflection) assume the syntax compiles first.
php-src reference
Repro (verified 2026-06-20)
test/repro/maintainer_gap_asymmetric_visibility_compile.php:
<?php
class C {
public private(set) int $x = 1;
}
$c = new C();
echo $c->x, "\n";
Promoted-parameter variant (test/repro/maintainer_gap_promoted_private_set.php):
<?php
class D {
public function __construct(public private(set) int $x = 1) {}
}
$d = new D();
echo $d->x, "\n";
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php bin/vm.php test/repro/maintainer_gap_asymmetric_visibility_compile.php 2>&1 | head -3
php bin/vm.php test/repro/maintainer_gap_promoted_private_set.php 2>&1 | head -3
'
| Check |
Zend PHP 8.4+ |
VM today |
Property public private(set) compiles |
✅ |
Multiple access type modifiers are not allowed ❌ |
Promoted public private(set) compiles |
✅ |
same compile error ❌ |
External read $c->x |
prints value |
not reached |
Scope (PHP-in-PHP first)
| Area |
Files |
| Parser |
lib/Parser.php / grammar — emit asymmetric visibility CFG ops (partial hooks exist in lib/Compiler.php asymmetric*VisibilityFromCfgOp) |
| Compiler |
lib/Compiler.php — property + promoted-parameter declare paths |
| VM |
lib/VM.php — enforce get/set visibility asymmetry |
| JIT |
lib/JIT/AsymmetricVisibilityGuard.php — route through VM PHP trampoline per #1492 |
Done when
Links
Category
language· php-src-strictProblem
PHP 8.4 asymmetric property visibility (
public private(set) int $x) is valid syntax. This compiler rejects it at parse/compile withMultiple access type modifiers are not allowed, blocking PHP 8.4 language parity.Related runtime gaps (#9842 private(set) write message, #6772 reflection) assume the syntax compiles first.
php-src reference
Zend/zend_compile.c—zend_compile_property_info(), asymmetric visibility flagsZend/zend_API.c—ZEND_ACC_ASYMMETRIC_*visibilityZend/zend_language_parser.y—property_modifiergrammar (PHP 8.4)Repro (verified 2026-06-20)
test/repro/maintainer_gap_asymmetric_visibility_compile.php:Promoted-parameter variant (
test/repro/maintainer_gap_promoted_private_set.php):public private(set)compilesMultiple access type modifiers are not allowed❌public private(set)compiles$c->xScope (PHP-in-PHP first)
lib/Parser.php/ grammar — emit asymmetric visibility CFG ops (partial hooks exist inlib/Compiler.phpasymmetric*VisibilityFromCfgOp)lib/Compiler.php— property + promoted-parameter declare pathslib/VM.php— enforce get/set visibility asymmetrylib/JIT/AsymmetricVisibilityGuard.php— route through VM PHP trampoline per #1492Done when
1$c->x = 2throws Error with ZendCannot modify private(set) propertymessage (see Language: private(set) property hook write — wrong 'read-only' Error not private(set) message (Zend/zend_property_hooks.c) #9842)test/compliance/cases/language/asymmetric_visibility_compile.phptgreenLinks