PHP Variable Scope and $GLOBALS

Understand function boundaries, global access, static locals and closure capture before sharing state.

Lesson 32 of 86Beginner10 min read

Variable scope determines where a name is available. A variable defined at the top of a PHP file is not automatically available inside every function. A function has its own local scope, which helps it work without accidentally reading or changing unrelated application variables. You usually connect the scopes by passing arguments and returning a result.

PHP also provides global, the $GLOBALS array, static local variables and closure capture. These tools are useful to understand even when you prefer explicit function parameters. This guide shows what each one does, how included files inherit scope, and why shared state can make apparently simple functions harder to test.

Local variables and function parameters

Each ordinary function call creates a local scope. Its parameters and variables belong to that invocation. Two functions can use a variable named $total without sharing the same storage. A variable in the surrounding file is outside the function unless you bring it in through a supported mechanism.

An if, foreach or while block does not create a separate variable scope in PHP. A variable assigned inside a condition can remain available afterward, provided that assignment actually ran. If the branch did not run, reading the variable can produce an undefined-variable warning. Initialize a value before conditional work when later code always needs it.

Use a parameter when a function needs data and a return value when it produces data. This makes the relationship visible at the call site. The function becomes easy to reuse with different inputs, and a test can call it without arranging hidden global state. Passing a value does not mean passing every variable in the application; identify only the dependencies the function truly needs.

global and $GLOBALS

Inside a function, global $counter; links the local name to the global variable of that name. Assigning to it then changes shared global state. $GLOBALS['counter'] provides another way to access the global variable, using an array-like name lookup. $GLOBALS is a superglobal, so the array itself is available inside functions without another declaration.

These mechanisms can be practical in legacy code, small bootstrap scripts or integrations that expose global variables. They should not become the default way to connect every function. Hidden dependencies make call order matter: one function may work only after another establishes a global value. Unrelated tests can also interfere when they modify the same name.

Modern PHP restricts operations on the $GLOBALS container. Since PHP 8.1, the whole array cannot be reassigned or changed through operations that overwrite its structure as a unit. Access individual named entries instead when maintaining code that genuinely requires global state. Prefer redesigning a dependency as an argument when you control the surrounding API.

Static locals and persistence boundaries

A static local variable belongs to a function but retains its value between calls in the same running execution. Declare it with static $calls = 0;. It is useful for a small internal counter or a cached result when the lifetime is well understood. It does not automatically become shared between all web requests or servers.

Long-lived workers change the practical lifetime of in-memory state. A static cache that appears harmless in a traditional request can survive several jobs in a worker. Decide whether state should reset between tasks. If cached results depend on a user, locale or configuration, include those dependencies in the cache design rather than assuming one value works forever.

Do not confuse a static local with a static class property. Both can retain values, but they belong to different language structures. A local static is accessed only inside its function. A class property is accessed through class syntax and can have visibility restrictions. Choose the mechanism that represents who owns the state.

Closures and included files

An anonymous function captures selected outer variables through use ($name). Capture by value records the value for the closure; capture by reference with use (&$name) shares a variable. Arrow functions capture referenced outer variables by value automatically. Objects captured by value still refer to the same object, so capture is not a deep clone.

An included file runs in the scope where the include occurs. Including a file inside a function therefore exposes that function's local variables to the included code. This can be useful for a simple template, but it also creates implicit dependencies between files. Give included scripts clear responsibilities and avoid letting them silently change many local names.

The PHP variable scope manual describes local, global and static behavior. When a name seems to disappear, inspect the function boundary first. The problem is often scope, not a misspelling or a need to use $GLOBALS everywhere.

PHP Variable Scope and $GLOBALS Examples

Each example shows the code, the output it produces and what each part does.

Example 1

Explicit input instead of hidden global access

The outer tax rate becomes the second argument. Inside the function it has the local name $rate. The function does not need to know whether the caller obtained the value from a constant, configuration array or test fixture. Formatting happens at output, separate from the calculation.

PHP
<?php
$taxRate = 0.1;
function withTax(float $price, float $rate): float {
    return $price * (1 + $rate);
}
echo number_format(withTax(20, $taxRate), 2, '.', '') . PHP_EOL;
Output
22.00
Example 2

See a global change explicitly

This function has a side effect instead of returning a count. The demonstration is intentionally small so you can see that both calls update the same storage. In an application, a visitor counter also needs persistent storage and concurrency handling; a PHP variable usually lasts only for the current execution.

PHP
<?php
$visits = 0;
function recordVisit(): void {
    global $visits;
    $visits++;
}
recordVisit();
recordVisit();
echo $GLOBALS['visits'] . PHP_EOL;
Output
2

PHP Variable Scope and $GLOBALS in Real Projects

Practical task: a function-local sequence

Write a function that returns the next ticket number during one script execution. Start at one and keep the counter private to the function. This is a learning exercise about lifetime, not a production ticketing design: real unique tickets need persistent storage and a strategy for simultaneous requests.

PHP
<?php
function nextLocalTicket(): int {
    static $ticket = 0;
    return ++$ticket;
}
echo nextLocalTicket() . PHP_EOL;
echo nextLocalTicket() . PHP_EOL;
echo nextLocalTicket() . PHP_EOL;
Output
1
2
3

The static initializer establishes the starting value, and each call updates the retained local storage. A normal $ticket = 0 assignment inside the function would reset the number on every call. Try that change and explain why all three results become one. Then consider how you would replace this example with an injected counter service for easier reset and testing.

PHP Variable Scope and $GLOBALS FAQ

Does an if block create a new scope?

No in PHP. A function boundary does. A variable assigned in an if block can be used afterward only if the relevant assignment happened.

Can I read superglobals inside a function?

Yes. Their special availability is why $GLOBALS and request superglobals do not need global. Input still requires validation.

Does static save a value after the server restarts?

No. It is in-memory state for the current process execution and does not replace a database or file.

Why prefer parameters?

They show dependencies at the call site and let different callers supply different data. That usually makes functions easier to understand and verify.

Can a closure change an outer variable?

An ordinary closure can capture it by reference. Use that deliberately because the resulting shared mutation can be less obvious than returning a result.

PHP Variable Scope and $GLOBALS Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Multiple choiceeasy

Which structure creates an ordinary local variable scope in PHP?

PHP Variable Scope and $GLOBALS Quiz

2 questions to check what you learned.

  1. What is usually the clearest way to supply a tax rate to a calculation function?

    • Hope the outer variable is automatically local
    • Pass it as an argument
    • Rename it with uppercase letters
  2. Which declaration retains a function-local value across calls in one execution?

    • global only
    • public only
    • static