4 / 12
Guide Book Β· Chapter 4

Variables, scope & references

Assignment copies, objects are handles, `&` makes an alias β€” and why PHP has no block scope but does have `static`.

A PHP variable is a name bound to a value. $ starts the name; the rest is a letter or _ followed by letters, digits or _.

php
<?php

$name = 'Ada';
$_private = 1;
$year2026 = 2026;

echo "$name $_private $year2026\n";
echo isset($undefined) ? 'set' : 'not set', "\n";

Assignment copies β€” lazily

$b = $a gives $b its own copy. Changing one never changes the other.

php
<?php

$a = [1, 2, 3];
$b = $a;
$b[] = 4;

echo count($a), ' vs ', count($b), "\n";   // 3 vs 4

Objects are the exception

An object variable holds a handle, not the object. Copying the variable copies the handle; both names still reach the same object.

php
<?php

class Counter {
    public int $n = 0;
}

$a = new Counter();
$b = $a;          // copies the handle
$b->n = 5;

echo $a->n, "\n";   // 5 β€” same object

$c = clone $a;    // a real copy
$c->n = 99;
echo $a->n, ' ', $c->n, "\n";   // 5 99

⚠️ clone is shallow: properties holding objects are still shared with the original. Define __clone() to deep-copy the ones that matter.

References: a second name for the same slot

& makes two names refer to one value. Unlike an object handle, this works for any type, and unsetting one name leaves the other alone.

php
<?php

$a = 1;
$b = &$a;      // $b is another name for $a
$b = 42;

echo $a, "\n";     // 42

unset($b);         // breaks the link, not the value
echo $a, "\n";     // 42

References appear in three more places: foreach by reference, reference parameters, and reference returns.

php
<?php

$prices = [10, 20, 30];

foreach ($prices as &$p) {
    $p *= 2;
}
unset($p);            // always unset after a by-reference foreach

print_r($prices);

function addTax(array &$cart): void {
    $cart['tax'] = 5;
}

$cart = ['items' => 2];
addTax($cart);
print_r($cart);
php
<?php

$a = [1, 2, 3];
foreach ($a as &$v) {}
foreach ($a as $v) {}
print_r($a);          // [1, 2, 2] β€” not [1, 2, 3]

Scope: functions, and nothing else

PHP has function scope. A function cannot see the variables around it, and β€” unlike C, Java or JavaScript's let β€” an if or for block creates no scope of its own.

php
<?php

$outer = 'global';

function show(): void {
    echo isset($outer) ? 'visible' : "not visible inside a function\n";
}
show();

for ($i = 0; $i < 3; $i++) {
    $insideLoop = $i;
}
echo "after the loop: \$i is $i, \$insideLoop is $insideLoop\n";

To reach a global from inside a function, say so β€” with global or $GLOBALS.

php
<?php

$config = ['debug' => true];

function readConfig(): void {
    global $config;
    echo 'debug: ', var_export($config['debug'], true), "\n";
}
readConfig();

πŸ’‘ Tip: Almost every use of global is better as a parameter. It makes the dependency visible, testable and safe to call twice.

static: a variable that outlives the call

A static local is initialised once and keeps its value between calls to that function β€” but only within a single run of the script.

php
<?php

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

echo nextId(), nextId(), nextId(), "\n";   // 123

Variable variables

$$name uses the value of $name as a variable name. It exists, it is occasionally useful in templating, and it makes code impossible to grep.

php
<?php

$field = 'email';
$$field = 'ada@example.com';

echo $email, "\n";
echo ${'fi' . 'eld'}, "\n";

⚠️ Reach for an array before reaching for a variable variable. $data['email'] does the same job and can be searched, typed and iterated.

Reference: Variables and References Explained in the PHP Manual.

index.php
Loading editor…
No output yet
Press Run or βŒ˜β†΅ to compile and run your code.

Search

Jump to a lesson or a past run