phpdbg's opcode listing does not include the bodies of property hooks

Ouverte
#25,338 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

Évaluation

Cette issue n'a pas encore été évaluée.

Description

Bug SAPI: phpdbg Status: Needs Triage

Description

phpdbg's -p option prints the opcodes of the main script, its functions, and the methods of its classes. It does not print the opcodes of property hooks (PHP 8.4+), and they cannot be selected by name either.

The following code (hooks.php):

<?php declare(strict_types=1);
final class Temperature
{
    public float $celsius = 0.0 {
        set {
            if ($value < -273.15) {
                throw new ValueError('Below absolute zero');
            }

            $this->celsius = $value;
        }
    }

    public float $fahrenheit {
        get => $this->celsius * 9 / 5 + 32;
    }

    public function reset(): void
    {
        $this->celsius = 0.0;
    }
}

Listed with:

phpdbg -qrr '-p*' hooks.php

Resulted in this output:

$_main:
     ; (lines=1, args=0, vars=0, tmps=0)
     ; /path/to/hooks.php:1-23
L0023 0000 RETURN int(1)

user class: Temperature
1 methods: reset

Temperature::reset:
     ; (lines=3, args=0, vars=0, tmps=1)
     ; /path/to/hooks.php:18-21
L0020 0000 ASSIGN_OBJ THIS string("celsius")
L0020 0001 OP_DATA float(0)
L0021 0002 RETURN null

But I expected this output instead: the opcodes of Temperature::$celsius::set and Temperature::$fahrenheit::get listed after those of Temperature::reset, for instance:

Temperature::$celsius::set:
     ; (lines=10, args=1, vars=1, tmps=4)
     ; /path/to/hooks.php:5-11
L0004 0000 CV0($value) = RECV 1
L0006 0001 T1 = IS_SMALLER CV0($value) float(-273.15)
L0006 0002 JMPZ T1 0007
L0007 0003 T2 = NEW 1 string("ValueError")
L0007 0004 SEND_VAL string("Below absolute zero") 1
L0007 0005 DO_FCALL
L0007 0006 THROW T2
L0010 0007 ASSIGN_OBJ THIS string("celsius")
L0010 0008 OP_DATA CV0($value)
L0011 0009 RETURN null

Temperature::$fahrenheit::get:
     ; (lines=8, args=0, vars=0, tmps=4)
     ; /path/to/hooks.php:15-15
L0015 0000 T0 = FETCH_OBJ_R THIS string("celsius")
...

(The opcodes above are taken from OPcache's dump of the same file on PHP 8.6 with opcache.opt_debug_level=0x40010000.)

The hooks are compiled: OPcache's debug dump of the same file (php -d opcache.enable_cli=1 -d opcache.opt_debug_level=0x10000 -r 'opcache_compile_file("hooks.php");') contains Temperature::$celsius::set: and Temperature::$fahrenheit::get: with their opcodes.

The hooks cannot be listed individually either:

$ phpdbg -qrr '-p=Temperature::$celsius::set' hooks.php
[The method Temperature::$celsius could not be found]

Cause

phpdbg_print_opcodes_ce() in sapi/phpdbg/phpdbg_print.c prints the methods in ce->function_table (and its header counts them: "1 methods: reset"). Property hooks are not stored in the function table but in zend_property_info->hooks (Zend/zend_compile.h), so they are skipped. The lookup for -p=Class::method (phpdbg_print_opcodes_method_ce()) also only searches ce->function_table.

zend_foreach_op_array() in Zend/Optimizer/zend_optimizer.c shows how to reach the hooks: it iterates ce->properties_info and visits hooks[i] for each property declared by the class (property->ce == ce), skipping hooks that are copied from traits (ZEND_ACC_TRAIT_CLONE). phpdbg_print_opcodes_ce() could do the same after printing the methods.

PHP Version
PHP 8.5.12 (cli) (built: Oct 19 2026 17:02:46) (NTS gcc x86_64)
Copyright (c) The PHP Group
Built by Remi's RPM repository <https://rpms.remirepo.net/> #StandWithUkraine #NoAI
Zend Engine v4.5.12, Copyright (c) Zend Technologies
    with Xdebug v3.5.3, Copyright (c) 2002-2026, by Derick Rethans
    with Zend OPcache v8.5.12, Copyright (c), by Zend Technologies
Operating System

Fedora 45

Langage dominant
C
Étoiles
41.8k
Forks
8.5k
Merge moyen
2 j 12 h
PR mergées (30 j)
137

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de php/php-src

Toutes les issues de php/php-src

Issues similaires

Plus d'issues C

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.