What scope means
The scope of a variable is the part of the program where it can be used. PHP's rule is simple and strict: every function has its own private set of variables. Variables created outside any function live in the global scope, and a function cannot see them.
<?php
$shopName = "Himanshu's Shop";
function printWelcome(): void
{
echo "Welcome to " . ($shopName ?? "an unknown shop") . "\n";
}
printWelcome();
echo "Outside the function: $shopName\n";Welcome to an unknown shop
Outside the function: Himanshu's ShopInside printWelcome(), $shopName is a brand-new local variable that has never been set. If you came from JavaScript, this is the big difference: PHP functions do not automatically see variables from the code around them.
The same separation works the other way. Variables created inside a function disappear when it returns, and they never clash with variables of the same name elsewhere:
<?php
$total = 999;
function calculate(): int
{
$total = 10 + 20; // a different $total, local to this call
return $total;
}
echo calculate() . "\n";
echo $total . "\n";30
999This isolation is a good thing. A function's behaviour depends only on its parameters and what it creates itself, so you can understand it on its own.
Pass values in, return values out
The right way to give a function data is as an argument, and the right way to get data back is with return:
<?php
function welcome(string $shopName): string
{
return "Welcome to $shopName";
}
$shopName = "Himanshu's Shop";
echo welcome($shopName) . "\n";Welcome to Himanshu's ShopThe global keyword
PHP does let a function reach into the global scope. The global keyword imports a global variable by name, and the $GLOBALS array holds every global variable:
<?php
$visits = 0;
function countVisit(): void
{
global $visits;
$visits++;
}
countVisit();
countVisit();
echo "Visits: $visits\n";
echo "Via \$GLOBALS: " . $GLOBALS['visits'] . "\n";Visits: 2
Via $GLOBALS: 2It works, but it is rarely a good idea. A function that uses global has a hidden input and a hidden output: you cannot tell from its signature that it reads and changes $visits, any other code can change the same variable, and testing it means setting up global state first. Old PHP code, including early WordPress plugins, uses globals a lot; modern code passes values explicitly or uses objects.
Static variables
Sometimes a function needs to remember something between its own calls, such as a counter or a cached result. A static variable is local to the function (no other code can see it), but it keeps its value after the function returns:
<?php
function nextInvoiceNumber(): string
{
static $number = 1000;
$number++;
return "INV-$number";
}
echo nextInvoiceNumber() . "\n";
echo nextInvoiceNumber() . "\n";
echo nextInvoiceNumber() . "\n";INV-1001
INV-1002
INV-1003The line static $number = 1000; runs only the first time; later calls reuse the stored value. A classic use is caching an expensive result for the rest of the request:
<?php
function settings(): array
{
static $cache = null;
if ($cache === null) {
echo "(loading settings once)\n";
$cache = ['currency' => 'INR', 'perPage' => 20];
}
return $cache;
}
echo settings()['currency'] . "\n";
echo settings()['perPage'] . "\n";(loading settings once)
INR
20Remember that PHP on a web server starts fresh for every request, so a static variable lasts only for one page load, not between visitors. Anything that must survive between requests belongs in a session, a file or a database.
Scope in loops and blocks
Unlike many languages, PHP has no block scope. A variable created inside an if or a loop is still there after it:
<?php
foreach (["Mug", "Bottle"] as $product) {
$last = $product;
}
echo "Last product: $last\n";
echo "Loop variable still set: $product\n";Last product: Bottle
Loop variable still set: BottleOnly functions (and the closures and classes coming later) create a new scope.
Common mistakes
- Expecting a function to see outside variables. Pass them as arguments.
- Reaching for global to fix that, instead of adding a parameter.
- Expecting static to persist between web requests. It resets on every request.
- Assuming a loop variable is gone after the loop. It keeps the last value.
Exercise
The function below should add an order to a running total, but it always prints 0. Fix it without using global, so that the final total is 155.
<?php
$runningTotal = 0;
function addOrder($amount)
{
$runningTotal = $runningTotal + $amount;
}
addOrder(100);
addOrder(55);
echo $runningTotal;Show one possible answer
Inside the function $runningTotal is a different, undefined variable. Pass the total in and return the new one:
<?php
function addOrder(float $runningTotal, float $amount): float
{
return $runningTotal + $amount;
}
$runningTotal = 0;
$runningTotal = addOrder($runningTotal, 100);
$runningTotal = addOrder($runningTotal, 55);
echo $runningTotal . "\n";155Key points
- Variables created outside functions are global; variables inside a function are local to that call.
- A function cannot see global variables unless they are passed in as arguments or imported with global.
- static $count = 0; keeps a variable's value between calls of the same function.
- Prefer passing values in and returning results over global variables.