Skip to content

Language: empty() on property hooks must not invoke get hook (zend_property_hooks.c) #8901

Description

@PurHur

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.phpOP_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)

  • Repro prints bool(false) + ok on VM without invoking get hook
  • empty($obj->virtualGetOnly) on write-only virtual hook matches Zend Error/behavior
  • ./script/ci-fast.sh --filter property_hook_empty green

Related

#8870 foreach by-ref hooks · #5203 get_object_vars hooks · #6484 write-only reads · #1492

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:vmVirtual machineenhancementNew feature or requestimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimphase-2:languagePhase 2 – language features

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions