OPcache folds FETCH_CONSTANT across later DECLARE_CONST when zend_execute_internal is set
@arnaud-lb ya está trabajando en esto.
Desde el 13/1/2026.
Evaluación
Este issue todavía no se ha evaluado.
Descripción
Description
OPcache folds FETCH_CONSTANT across later DECLARE_CONST when zend_execute_internal is set, changing program semantics.
When an extension sets zend_execute_internal (even to a no-op), zend_get_call_op chooses the generic ZEND_DO_FCALL for INIT_FCALL_BY_NAME. This appears to affect OPcache pass 1: in a script that calls a function before a constant is declared, OPcache replaces ZEND_FETCH_CONSTANT inside that function with the later-declared literal, changing behavior from a fatal error to printing the constant value.
Reproducer
INI:
opcache.enable=1
opcache.enable_cli=1
opcache.optimization_level=-1
opcache.opt_debug_level=0x10000
Code:
<?php
printf("A=%s\n", getA());
const A = "hello";
function getA() { return A; }
Without any module: the script fatals (Undefined constant "A"), and getA keeps FETCH_CONSTANT (see bug66251).
With a module that only does:
orig_execute_internal = zend_execute_internal;
zend_execute_internal = our_own_execute_internal;
the optimizer turns getA into RETURN "hello" and the script prints A=hello.
Question
Is this behavior expected when an extension hooks zend_execute_internal?
Output (for reference).
No zend_execute_internal (before and after optimizer):
$_main:
; (lines=8, args=0, vars=0, tmps=2)
; (before optimizer)
; /bin/bug66251.php:1-6
; return [] RANGE[0..0]
0000 INIT_FCALL 2 112 string("printf")
0001 SEND_VAL string("A=%s\n") 1
0002 INIT_FCALL_BY_NAME 0 string("getA")
0003 V0 = DO_FCALL_BY_NAME
0004 SEND_VAR V0 2
0005 DO_ICALL
0006 DECLARE_CONST string("A") string("hello")
0007 RETURN int(1)
getA:
; (lines=3, args=0, vars=0, tmps=1)
; (before optimizer)
; /bin/bug66251.php:4-4
; return [] RANGE[0..0]
0000 T0 = FETCH_CONSTANT string("A")
0001 RETURN T0
0002 RETURN null
$_main:
; (lines=8, args=0, vars=0, tmps=1)
; (after optimizer)
; /bin/bug66251.php:1-6
0000 INIT_FCALL 2 112 string("printf")
0001 SEND_VAL string("A=%s\n") 1
0002 INIT_FCALL 0 96 string("geta")
0003 V0 = DO_UCALL
0004 SEND_VAR V0 2
0005 DO_ICALL
0006 DECLARE_CONST string("A") string("hello")
0007 RETURN int(1)
getA:
; (lines=2, args=0, vars=0, tmps=1)
; (after optimizer)
; /bin/bug66251.php:4-4
0000 T0 = FETCH_CONSTANT string("A")
0001 RETURN T0
zend_execute_internal is set (before and after optimizer):
$_main:
; (lines=8, args=0, vars=0, tmps=2)
; (before optimizer)
; /bin/bug66251.php:1-6
; return [] RANGE[0..0]
0000 INIT_FCALL 2 112 string("printf")
0001 SEND_VAL string("A=%s\n") 1
0002 INIT_FCALL_BY_NAME 0 string("getA")
0003 V0 = DO_FCALL
0004 SEND_VAR V0 2
0005 DO_FCALL
0006 DECLARE_CONST string("A") string("hello")
0007 RETURN int(1)
getA:
; (lines=3, args=0, vars=0, tmps=1)
; (before optimizer)
; /bin/bug66251.php:4-4
; return [] RANGE[0..0]
0000 T0 = FETCH_CONSTANT string("A")
0001 RETURN T0
0002 RETURN null
$_main:
; (lines=8, args=0, vars=0, tmps=1)
; (after optimizer)
; /bin/bug66251.php:1-6
0000 INIT_FCALL 2 112 string("printf")
0001 SEND_VAL string("A=%s\n") 1
0002 INIT_FCALL 0 80 string("geta")
0003 V0 = DO_UCALL
0004 SEND_VAR V0 2
0005 DO_FCALL
0006 DECLARE_CONST string("A") string("hello")
0007 RETURN int(1)
getA:
; (lines=1, args=0, vars=0, tmps=0)
; (after optimizer)
; /bin/bug66251.php:4-4
0000 RETURN string("hello")
PHP Version
PHP 8.5.1 (cli) (built: Dec 17 2025 08:47:15) (ZTS)
Copyright (c) The PHP Group
Zend Engine v4.5.1, Copyright (c) Zend Technologies
with Zend OPcache v8.5.1, Copyright (c), by Zend Technologies
- Lenguaje dominante
- C
- Estrellas
- 40.4k
- Forks
- 8.2k
- Merge medio
- 2 d 15 h
- PR fusionados (30 d)
- 103
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de php/php-src
-
Bug SAPI: cli_server Status: Verified
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
-
Bug Status: Needs Triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
-
Bug Status: Needs Triage
Dificultad 1/5 Menos de una hora Aptitud para principiantes 90/100
-
Bug Status: Needs Triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
-
Flaky hrtime.phpt test AbiertoBug Category: Tests Status: Verified
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
Todos los issues de php/php-src
Issues similares
-
[adam] AdamNet network read doesn't cap to MAX_ADAM_PACKET_LEN, overflows client receive buffers Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
FujiNetWIFI/fujinet-firmware#1649 · 2 comentarios ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
HarbourMasters/Shipwright#7229 ·
-
Error while building from source Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
riscv-software-src/riscv-isa-sim#2435 · 1 comentario ·
-
bug Self Built Image SNAPSHOT Supported Device target/ramips
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100