PHPVariable Scope (local, global, static)

Variable Scope (local, global, static)

Scope determines where in your script a variable's name is visible and how long its value survives. PHP's default rule is simple but surprising to newcomers coming from JavaScript: every function has its own isolated scope, and it cannot see variables from the surrounding script unless you explicitly let it in.

Local scope by default

A variable created inside a function only exists inside that function. A variable created at the top level of a script (often called the "global scope") only exists there — a function body cannot read it just because it happens to be defined nearby.

Functions cannot see outer variables by default

PHP
<?php
$budget = 5000;

function showBudget(): void {
    // $budget here is undefined, NOT the $5000 above
    echo $budget ?? 'undefined';
}

showBudget();
undefined
The global keyword

To let a function read or modify a variable from the outer scope, you can declare it global inside the function. This creates a reference to the outer variable rather than a copy.

Reaching into the global scope

PHP
<?php
$budget = 5000;

function spend(int $amount): void {
    global $budget;
    $budget -= $amount;
}

spend(1200);
echo $budget;
3800
Why global is discouraged
`global` makes a function's behaviour depend on hidden state outside its parameter list — you cannot tell what `spend()` will do just by reading its signature. This makes code harder to test (you must set up global state first) and harder to reason about as a codebase grows. Prefer passing values in as parameters and returning results, or grouping shared state in a class, instead of reaching for `global`.

The same logic without global

PHP
<?php
function spend(int $budget, int $amount): int {
    return $budget - $amount;
}

$budget = 5000;
$budget = spend($budget, 1200);
echo $budget;
3800
Superglobals are the exception

PHP has a handful of "superglobal" arrays — $_GET, $_POST, $_SESSION, $_SERVER, $_ENV, $_COOKIE, $_FILES, and $GLOBALS — that are visible in every scope automatically, no global keyword required. $GLOBALS in particular is a live array of every variable in the true global scope, and can be used as an alternative to the global keyword.

$GLOBALS as an array view of global scope

PHP
<?php
$budget = 5000;

function spendViaGlobals(int $amount): void {
    $GLOBALS['budget'] -= $amount;
}

spendViaGlobals(500);
echo $budget;
4500
Static variables: state that survives calls

A variable declared static inside a function keeps its value between calls instead of being reset each time the function runs. It is initialised exactly once, the first time the function executes.

A counter that remembers itself

PHP
<?php
function nextId(): int {
    static $id = 0;
    $id++;
    return $id;
}

echo nextId(); // 1
echo nextId(); // 2
echo nextId(); // 3
1
2
3
static is per-function, not per-call-site
The static value is tied to the function itself, not to where it is called from. If two different parts of your code both call `nextId()`, they share the same counter — there is only one `$id` living in that function's static storage for the whole request.
Closures and the use() keyword

Anonymous functions (closures) follow the same local-scope rule as named functions: they do not automatically see variables from the scope they were defined in. To capture a variable from the surrounding scope, list it in a use() clause. This is only a brief mention here — closures and use() (including capture by reference with use (&$var)) are covered in full on their own page.

Capturing a variable into a closure

PHP
<?php
$taxRate = 0.13;

$addTax = function (float $price) use ($taxRate): float {
    return $price * (1 + $taxRate);
};

echo $addTax(100);
113
Scope summary
  • Local — the default; variables created inside a function or method exist only for that call.

  • Global — variables at the top level of a script; functions need global or $GLOBALS to reach them.

  • Static — local variables that persist their value across repeated calls to the same function.

  • Superglobals$_GET, $_POST, $_SESSION, and friends are always visible, in any scope.

Tip
If you find yourself reaching for `global` to share state between multiple functions, that is usually a sign the functions belong together as methods on a class, with the shared state as a property. It gives you the same convenience without the hidden coupling.