Category
language · php-src-strict
Problem
On PHP 8.4 property hooks, empty($obj->hooked) must use the same isset-style backing check as Zend and must not call the get hook. This compiler invokes the get hook, so a throwing getter fatals instead of returning false.
Distinct from #5203 (get_object_vars must call get hooks) — empty()/isset() are the inverse rule.
php-src reference
Repro
Save as test/repro/issue_property_hook_empty.php:
<?php
class C {
public string $x {
get { throw new Exception('get must not run for empty()'); }
set => $this->backing = $value;
}
private string $backing = 'a';
}
$c = new C();
var_dump(empty($c->x));
echo "ok\n";
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php test/repro/issue_property_hook_empty.php
php bin/vm.php test/repro/issue_property_hook_empty.php
'
| Runtime |
Output |
| Zend PHP 8.4+ |
bool(false) then ok (backing initialized; get hook not called) |
| VM (wrong) |
Fatal error: Uncaught Exception: get must not run for empty() |
Scope (PHP-in-PHP)
| Layer |
Path |
| VM |
lib/VM.php — OP_EMPTY / isset path for hooked properties; reuse hook-backing probe used by ??= (#6472) |
| Compiler |
No syntax change |
| JIT/AOT |
Mirror isset/empty hook guard when lowering exists |
| Tests |
test/compliance/cases/language/property_hook_empty.phpt |
Done when (php-src-strict)
Related
#8870 foreach by-ref hooks · #5203 get_object_vars hooks · #6484 write-only reads · #1492
Category
language· php-src-strictProblem
On PHP 8.4 property hooks,
empty($obj->hooked)must use the same isset-style backing check as Zend and must not call the get hook. This compiler invokes the get hook, so a throwing getter fatals instead of returningfalse.Distinct from #5203 (
get_object_varsmust call get hooks) —empty()/isset()are the inverse rule.php-src reference
Zend/zend_property_hooks.c—zend_isset_property_ex/ empty semanticsZend/zend_operators.c—emptyopcode on hooked propertiesRepro
Save as
test/repro/issue_property_hook_empty.php:bool(false)thenok(backing initialized; get hook not called)Fatal error: Uncaught Exception: get must not run for empty()Scope (PHP-in-PHP)
lib/VM.php—OP_EMPTY/ isset path for hooked properties; reuse hook-backing probe used by??=(#6472)test/compliance/cases/language/property_hook_empty.phptDone when (php-src-strict)
bool(false)+okon VM without invoking get hookempty($obj->virtualGetOnly)on write-only virtual hook matches Zend Error/behavior./script/ci-fast.sh --filter property_hook_emptygreenRelated
#8870 foreach by-ref hooks · #5203 get_object_vars hooks · #6484 write-only reads · #1492