Category
Language · php-src-strict / define() compile-time prescan
Problem
define('NAME', literal) inside a user function (or method) emits Constant NAME already defined on VM/JIT. Zend 8.2.32 registers the constant once and is silent.
Top-level define('NAME', literal) and define($runtimeName, literal) already match Zend. The extra warning is the compile-time prescan (Compiler::prescanDefineFuncCall / storeCompileTimeGlobalConst, issue #204) seeding the constant, then the still-emitted runtime define() / TYPE_DECLARE_GLOBAL_CONST trying again when the function runs.
Probed 2026-08-18 @ 87cba84dc2 — Zend 8.2.32 vs php bin/vm.php / php bin/jit.php.
| Repro |
Zend 8.2.32 |
VM/JIT |
function f() { define('C', 1); } f(); |
silent; defined('C')===true |
Warning: Constant C already defined (attributed to the call site of f(), not the define() line) |
file-scope define('C', 1); |
silent |
silent ✓ |
define('C'.'X', 1); (runtime name) |
silent |
silent ✓ |
php-src reference
PHP implementation target
lib/Compiler.php — prescanDefineFuncCall / tryCompileDefineAsGlobalConst: do not seed the runtime constant table for define() that will still run inside a function body; either elide the runtime call xor skip prescan, never both
ext/standard/define_.php — runtime define() should remain the php-src-strict path for non-elided calls
lib/VM.php TYPE_DECLARE_GLOBAL_CONST — same uniqueness as Zend zend_register_constant
- No new
runtime/*.c
Repro
./script/docker-exec.sh -- bash -lc 'php bin/vm.php test/repro/maintainer_gap_define_inside_function.php'
./script/docker-exec.sh -- bash -lc 'php bin/jit.php test/repro/maintainer_gap_define_inside_function.php'
./script/docker-exec.sh -- bash -lc 'php test/repro/maintainer_gap_define_inside_function.php' # Zend baseline
<?php
error_reporting(E_ALL);
function probe_define(): void
{
define('PROBE_C_ISOLATED', 1);
echo 'defined_ci=', var_export(defined('probe_c_isolated'), true), "\n";
echo 'defined_CS=', var_export(defined('PROBE_C_ISOLATED'), true), "\n";
}
probe_define();
Done when
Category
Language· php-src-strict /define()compile-time prescanProblem
define('NAME', literal)inside a user function (or method) emitsConstant NAME already definedon VM/JIT. Zend 8.2.32 registers the constant once and is silent.Top-level
define('NAME', literal)anddefine($runtimeName, literal)already match Zend. The extra warning is the compile-time prescan (Compiler::prescanDefineFuncCall/storeCompileTimeGlobalConst, issue #204) seeding the constant, then the still-emitted runtimedefine()/TYPE_DECLARE_GLOBAL_CONSTtrying again when the function runs.Probed 2026-08-18 @
87cba84dc2— Zend 8.2.32 vsphp bin/vm.php/php bin/jit.php.function f() { define('C', 1); } f();defined('C')===trueWarning: Constant C already defined(attributed to the call site off(), not thedefine()line)define('C', 1);define('C'.'X', 1);(runtime name)php-src reference
Zend/zend_builtin_functions.c—PHP_FUNCTION(define)/zend_register_constantZend/zend_constants.c— user constants are registered whendefine()executes, not when the containing function is compiledPHP implementation target
lib/Compiler.php—prescanDefineFuncCall/tryCompileDefineAsGlobalConst: do not seed the runtime constant table fordefine()that will still run inside a function body; either elide the runtime call xor skip prescan, never bothext/standard/define_.php— runtimedefine()should remain the php-src-strict path for non-elided callslib/VM.phpTYPE_DECLARE_GLOBAL_CONST— same uniqueness as Zendzend_register_constantruntime/*.cRepro
Done when
define('LIT', …)inside a function/method is silent on first execution (Zend); second call still warnsalready defineddefine()unchanged (already green)defined('LIT')/constant('LIT')still see the value after the first call.phptundertest/compliance/cases/language/define()in the function and pre-registers the constant