Category
language · php-src-strict · compile-time fatal · $GLOBALS (sibling of #15627)
Problem
Wholesale writes to the $GLOBALS variable are accepted (rc=0). Zend 8.1+ is a compile-time fatal:
$GLOBALS can only be modified using the $GLOBALS[$name] = $value syntax
&$GLOBALS is already a compile fatal (#15627, Cannot acquire reference to $GLOBALS). Indexed $GLOBALS['x'] = 1 is valid on both sides (control). The remaining holes are assign / assign-op / unset of the $GLOBALS variable itself.
Verified 2026-08-18 @ 3633ba3bb9 vs Zend 8.2.32.
| Repro |
Zend 8.2.32 |
VM / JIT |
$GLOBALS = []; |
Fatal $GLOBALS can only be modified using the $GLOBALS[$name] = $value syntax |
accepted (rc=0) |
$GLOBALS += ['x' => 1]; |
same fatal |
accepted (rc=0) |
unset($GLOBALS); |
same fatal |
accepted (rc=0) |
$a = &$GLOBALS; (control, #15627) |
Fatal Cannot acquire reference to $GLOBALS |
same (match) |
$GLOBALS['x'] = 1; (control) |
rc=0 |
rc=0 |
php-src reference
- php/php-src
Zend/zend_compile.c — zend_compile_assign() / zend_compile_assign_op() / zend_compile_unset(); bare $GLOBALS as the write target → $GLOBALS can only be modified using the $GLOBALS[$name] = $value syntax
- PHP 8.1 “Restrict $GLOBALS” RFC; indexed
$GLOBALS[$name] remains the only legal write
PHP implementation target
lib/Compiler.php — extend the existing #15627 rejectGlobalsReferenceAcquisition() family: reject assign / += / unset when the target’s base name is GLOBALS (not $GLOBALS['k'] dim writes)
- Reuse
throwCompileError with the Zend sentence above
- Same compile path for JIT/AOT; no new
runtime/*.c logic
Repro
./script/docker-exec.sh -- bash -lc 'php bin/vm.php test/repro/maintainer_gap_globals_assign.php 2>&1 | head -5'
./script/docker-exec.sh -- bash -lc 'php bin/vm.php test/repro/maintainer_gap_globals_plus_assign.php 2>&1 | head -5'
./script/docker-exec.sh -- bash -lc 'php bin/vm.php test/repro/maintainer_gap_unset_globals.php 2>&1 | head -5'
./script/docker-exec.sh -- bash -lc 'php bin/jit.php test/repro/maintainer_gap_globals_assign.php 2>&1 | head -5'
<?php
$GLOBALS = [];
echo "accepted\n";
Done when
Category
language· php-src-strict · compile-time fatal ·$GLOBALS(sibling of #15627)Problem
Wholesale writes to the
$GLOBALSvariable are accepted (rc=0). Zend 8.1+ is a compile-time fatal:$GLOBALS can only be modified using the $GLOBALS[$name] = $value syntax
&$GLOBALSis already a compile fatal (#15627,Cannot acquire reference to $GLOBALS). Indexed$GLOBALS['x'] = 1is valid on both sides (control). The remaining holes are assign / assign-op / unset of the$GLOBALSvariable itself.Verified 2026-08-18 @
3633ba3bb9vs Zend 8.2.32.$GLOBALS = [];$GLOBALS += ['x' => 1];unset($GLOBALS);$a = &$GLOBALS;(control, #15627)$GLOBALS['x'] = 1;(control)php-src reference
Zend/zend_compile.c—zend_compile_assign()/zend_compile_assign_op()/zend_compile_unset(); bare$GLOBALSas the write target → $GLOBALS can only be modified using the $GLOBALS[$name] = $value syntax$GLOBALS[$name]remains the only legal writePHP implementation target
lib/Compiler.php— extend the existing#15627rejectGlobalsReferenceAcquisition()family: reject assign /+=/unsetwhen the target’s base name isGLOBALS(not$GLOBALS['k']dim writes)throwCompileErrorwith the Zend sentence aboveruntime/*.clogicRepro
Done when
$GLOBALS can only be modified using the $GLOBALS[$name] = $value syntaxfor=,+=, andunset($GLOBALS)$GLOBALS['x'] = 1still succeeds;&$GLOBALSstill uses the Language: $ref = &$GLOBALS must compile-time fatal — VM executes (Zend/zend_compile.c) #15627 reference fatal.phptguard undertest/compliance/cases/language/