$GLOBALS
$GLOBALS
What Is $GLOBALS?
In simple terms: $GLOBALS is a built-in array that contains every variable defined in the global scope. Its keys are the variable names (without $), and its values are the variables' values. Technically: $GLOBALS is a superglobal: it is available in every scope, including inside functions and methods. Reading $GLOBALS['name'] reads the global variable $name; assigning $GLOBALS['name'] = $value writes to it — from anywhere in the program.
$siteName = 'GoCourse'; // global variable
$GLOBALS['siteName']; // 'GoCourse' — accessible in any function
Why It Exists
Regular functions cannot see global variables (see Variables Scope). $GLOBALS (and the global keyword) provide a way to reach them. In early PHP applications, this was a common way to share configuration and state. Modern code avoids global state, but you will find $GLOBALS in legacy applications, some content management systems, and debugging code — so it is important to understand how it behaves.
Reading Global Variables in a Function
<?php
$siteName = 'GoCourse';
$year = 2026;
function footerText(): string
{
return '© ' . $GLOBALS['year'] . ' ' . $GLOBALS['siteName'];
}
echo footerText() . "\n";
Output
© 2026 GoCourse
Inside footerText(), $siteName and $year are not defined, but $GLOBALS['siteName'] and $GLOBALS['year'] read the global variables.
Writing Global Variables
<?php
$visitCount = 0;
function registerVisit(): void
{
$GLOBALS['visitCount']++;
}
function setTheme(string $theme): void
{
$GLOBALS['theme'] = $theme; // creates a new global variable
}
registerVisit();
registerVisit();
setTheme('dark');
echo "Visits: $visitCount\n";
echo "Theme: $theme\n";
Output
Visits: 2
Theme: dark
- Modifying
$GLOBALS['visitCount']changes the global$visitCount. - Assigning a new key creates a new global variable, here
$theme. This shows why global state is risky: after callingsetTheme(), a variable appears in the global scope that was never declared there. Code that reads$themedepends onsetTheme()having been called first.
$GLOBALS vs the global Keyword
<?php
$counter = 10;
function withGlobalKeyword(): void
{
global $counter;
$counter++;
}
function withGlobalsArray(): void
{
$GLOBALS['counter']++;
}
withGlobalKeyword();
withGlobalsArray();
echo $counter . "\n";
Output
12
global $name; | $GLOBALS['name'] | |
|---|---|---|
| Syntax | Declared once in the function, then used as $name | Array access each time |
| Visible as global at the point of use | No — later lines look like local variables | Yes — $GLOBALS is explicit on every line |
| Dynamic variable names | No | Yes: $GLOBALS[$name] |
| Typical use | Legacy code | Legacy code, debugging, framework internals |
Both mechanisms share the same drawbacks; neither is recommended for new application code.
PHP 8.1 Changes: $GLOBALS Is Restricted
Before PHP 8.1, $GLOBALS behaved like a special array whose modifications — even through copies — affected global variables. PHP 8.1 restricted its use to make PHP's internals simpler and behavior more predictable.
Writing the Whole Array Is No Longer Allowed
$GLOBALS = []; // compile-time error in PHP 8.1+
array_pop($GLOBALS); // error: $GLOBALS cannot be passed by reference
Writing individual elements still works: $GLOBALS['name'] = 'value';.
Copies Are Now Real Copies
<?php
$total = 10;
$copy = $GLOBALS;
$copy['total'] = 99;
echo $total . "\n";
Output (PHP 8.1 and newer)
10
Since PHP 8.1, assigning $GLOBALS to another variable creates an independent copy. Changing the copy does not affect the global $total. (In earlier versions, the change would have modified $total.)
Why Global State Should Be Avoided
<?php
$taxRate = 0.18;
function priceWithTax(float $price): float
{
return $price * (1 + $GLOBALS['taxRate']);
}
echo priceWithTax(100) . "\n";
$GLOBALS['taxRate'] = 0.05; // any code, anywhere, can change it
echo priceWithTax(100) . "\n";
Output
118
105
The same call returns different results because hidden global state changed between the calls. Problems with this design:
- Hidden dependency: the signature
priceWithTax(float $price)does not reveal that the function needs a tax rate. - Unpredictable behavior: any code can change
$taxRate, and finding where it changed means searching the entire codebase. - Hard to test: each test must set up and reset global variables, and tests can interfere with each other.
- Name collisions: two parts of the code (or two libraries) may use the same global name for different things.
Better Alternatives
| Need | Alternative |
|---|---|
| A value a function needs | Pass it as a parameter |
| A fixed value used everywhere | A constant (const TAX_RATE = 0.18;) or a class constant |
| Application configuration | A config array loaded once and passed where needed, or a configuration object |
| Shared services (database connection, logger) | Dependency injection: pass the service into the class or function that needs it |
<?php
function priceWithTax(float $price, float $taxRate): float
{
return $price * (1 + $taxRate);
}
echo priceWithTax(100, 0.18) . "\n";
echo priceWithTax(100, 0.05) . "\n";
Output
118
105
Now every input is visible in the call, and the function always returns the same result for the same arguments.
Legitimate Uses
$GLOBALS still has a few practical uses:
- Debugging: inspecting which global variables exist.
- Legacy code: maintaining older applications and plugins that rely on global variables.
- Dynamic access: reading a global whose name is known only at runtime (
$GLOBALS[$name]), for example in template engines or migration tools.
Example: Inspecting User-Defined Globals
<?php
$appName = 'GoCourse';
$version = '2.4.0';
$debug = false;
function userDefinedGlobals(): array
{
$builtIn = ['_GET', '_POST', '_COOKIE', '_FILES', '_SERVER', '_ENV', '_REQUEST', '_SESSION', 'argv', 'argc', 'GLOBALS'];
return array_diff_key($GLOBALS, array_flip($builtIn));
}
foreach (userDefinedGlobals() as $name => $value) {
echo "$name = " . var_export($value, true) . "\n";
}
Output (CLI)
appName = 'GoCourse'
version = '2.4.0'
debug = false
How It Works
$GLOBALSalso contains PHP's own superglobals and, in the command line,$argvand$argc.array_diff_key()removes those built-in names, leaving only the variables defined by the script.- The filtering happens inside a function, so its helper variable (
$builtIn) is local and does not appear in the result. The loop variables$nameand$valueare created only after the function has already returned its result.
Common Mistakes
Using $GLOBALS as a Configuration System
Effect: Hidden dependencies and unpredictable behavior. Fix: Pass configuration explicitly or use a configuration object.
Writing to $GLOBALS From Many Functions
Effect: Bugs that depend on the order in which functions are called. Fix: Return values from functions and assign them in one clear place.
Expecting Pre-8.1 Copy Behavior
Effect: Code that modifies a copy of $GLOBALS no longer changes global variables in PHP 8.1+. Fix: Write individual elements directly: $GLOBALS['name'] = $value;.
Reading Undefined Globals
Effect: Warnings and null values. Fix: Use $GLOBALS['name'] ?? $default, or better, avoid relying on globals.
Best Practices
- Avoid
$GLOBALSandglobalin new code; use parameters, return values, and constants. - Use dependency injection for shared services such as database connections.
- Limit
$GLOBALSto debugging, legacy maintenance, and rare dynamic-access cases. - In PHP 8.1+, write individual elements only; never assign or pass the whole array by reference. Official reference: https://www.php.net/manual/en/reserved.variables.globals.php