PHP 8.1: $GLOBALS
variable restrictions
$GLOBALS
is a special variable in PHP that references all variables in the global scope. $GLOBALS
is an associative array, with array keys being the global variable name, and the array key being the global variable. $GLOBALS
contains all global variables as well as other super global values such $_SERVER
, $_GET
, $_ENV
, etc. where applicable.
$foo = 'apple';
$GLOBALS['foo'] = 'banana';
echo $foo; // banana
Additionally, the $GLOBALS
array was always assigned by reference (prior to PHP 8.1), even if it visibly assigned by-value.
$foo = 'apple';
$my_vars = $GLOBALS;
$my_vars['foo'] = 'banana';
echo $foo; // banana
It adds a significant amount of technical complexity to support this $GLOBALS
variable behavior, particularly when the $GLOBALS
array itself is modified which affects multiple global variables at once.
$GLOBALS = get_new_vars();
From PHP 8,1 and later, certain changes to the $GLOBALS
array throws fatal errors. In general, modifying individual array elements is allowed, but making mass changes are not allowed.
$GLOBALS = get_new_vars();
Fatal error: $GLOBALS can only be modified using the $GLOBALS[$name] = $value syntax in ... on line ...
Restrictions and Changes
All changes that affect the $GLOBALS
array itself are not allowed since PHP 8.1. This includes destroying the $GLOBALS
array, overwriting it with a new value, array operations, and creating references to $GLOBALS
variable.
Mass changes to $GLOBALS
are no longer allowed
Overwriting, unsetting, or otherwise making mass changes to the $GLOBALS
array is no longer allowed.
For example, the all of the following modifications are allowed prior to PHP 8.1, but results in a fatal error in PHP 8.1 and later:
$GLOBALS = [];
$GLOBALS = ['foo' => 1, 'bar' => 2];
$GLOBALS = get_new_vars();
$GLOBALS =& $new_vars;
list($GLOBALS) = [1];
foreach ($new_var_c as $GLOBALS) {}
unset($GLOBALS);
Fatal error: $GLOBALS can only be modified using the $GLOBALS[$name] = $value syntax in ... on line ...
Referencing $GLOBALS
is no longer allowed
Prior to PHP 8.1, it was possible to create a reference to $GLOBALS
array, and modify that reference. All changes would then be reflected in the global variables as well.
$x =& $GLOBALS;
$x['foo'] = 'test';
echo $foo; // 'test';
From PHP 8.1, it is no longer allowed to create references to $GLOBALS
variable.
$x =& $GLOBALS;
Fatal error: Cannot acquire reference to $GLOBALS in ... on line ...
Further, it is no longer allowed to pass $GLOBALS
to a function that expects a parameter by-reference.
array_pop($GLOBALS);
Fatal error: Uncaught Error: array_pop(): Argument #1 ($array) cannot be passed by reference in ...:...
$GLOBALS['GLOBALS']
no longer exists
Prior to PHP 8.1, $GLOBALS
variable contained a reference to itself at $GLOBALS['GLOBALS']
. It no longer exists in PHP 8.1 and later.
isset($GLOBALS['GLOBALS']); // false
Backwards Compatibility Impact
Applications that mass-modify, unset, or populate the $GLOBALS
array might need to perform said operations on individual array keys, or otherwise they will result in fatal errors since PHP 8.1.
Further, creating references to the $GLOBALS
variable is no longer allowed, and it no longer behaves as if it was assigned when a standard variable is assigned $GLOBALS
(i.e. $var = $GLOBALS
).
It is rare for a PHP application to make such changes to the $GLOBALS
variable, and more often than not, there is a better approach to achieve the result, either using PSR-7 objects, or using mocking libraries when testing applications.