Pass by Reference

Yo Yogesh.M Updated 17 Oct 2026
6 min read ·Lesson 44 of 102
In this post

What Is Pass by Reference? In simple terms: Normally, a function receives a copy of each argument, so changes inside the function do not affect the caller. When a parameter is passed by reference , th

What Is Pass by Reference?

In simple terms: Normally, a function receives a copy of each argument, so changes inside the function do not affect the caller. When a parameter is passed by reference, the function works on the caller's original variable, and any change it makes is visible after the call.

Technically: Prefixing a parameter with & in the function declaration makes it a reference to the variable passed as the argument. The parameter and the caller's variable become two names for the same value.

function addTax(float &$price, float $ratePercent): void   // & marks $price as a reference

By Value vs By Reference

By Value (default)By Reference (&)
What the function receivesA copy of the valueThe caller's variable itself
Changes inside the functionAffect only the copyAffect the caller's variable
What can be passedAny expressionOnly a variable (or array element/property)
How results usually leave the functionreturnModifying the parameter

Syntax

function functionName(Type &$parameter)
{
    $parameter = /* new value */;   // changes the caller's variable
}

The & appears only in the declaration. The call looks like a normal call: functionName($variable);.

Example

<?php
function addTaxByValue(float $price, float $ratePercent): void
{
    $price = round($price * (1 + $ratePercent / 100), 2);
}

function addTax(float &$price, float $ratePercent): void
{
    $price = round($price * (1 + $ratePercent / 100), 2);
}

$a = 1000.0;
addTaxByValue($a, 18);
echo "By value: $a\n";

$b = 1000.0;
addTax($b, 18);
echo "By reference: $b\n";

Output

By value: 1000
By reference: 1180

How It Works

  • addTaxByValue() receives a copy. It changes the copy, which is discarded when the function ends, so $a is unchanged.
  • addTax() declares &$price, so $price is $b inside the function. Assigning to $price assigns to $b.

Built-in Functions That Use References

You have probably already used pass by reference through PHP's own functions:

<?php
// 1. Sorting modifies the array in place
$names = ['Ravi', 'Asha', 'Bala'];
sort($names);
echo implode(', ', $names) . "\n";

// 2. preg_match() fills the $matches array
preg_match('/(\d{4})-(\d{2})-(\d{2})/', 'Due on 2026-10-15', $matches);
echo "Year {$matches[1]}, month {$matches[2]}, day {$matches[3]}\n";

// 3. str_replace() reports how many replacements were made
$text = str_replace('cat', 'dog', 'cat & cat', $count);
echo "$text ($count replacements)\n";

// 4. array_push() adds to the original array
$queue = ['task-1'];
array_push($queue, 'task-2', 'task-3');
echo count($queue) . " tasks queued\n";

Output

Asha, Bala, Ravi
Year 2026, month 10, day 15
dog & dog (2 replacements)
3 tasks queued

In the PHP manual, reference parameters are marked with & in the signature — for example, sort(array &$array, int $flags = SORT_REGULAR): true and preg_match(string $pattern, string $subject, array &$matches = null, ...). Recognizing this & tells you that the function will modify the variable you pass.


Only Variables Can Be Passed by Reference

A reference must point to something that can be changed — a variable, an array element, or an object property. Literal values and function results have nowhere to store the change.

Passing a Literal

<?php
function addTax(float &$price, float $ratePercent): void
{
    $price = round($price * (1 + $ratePercent / 100), 2);
}

addTax(500.0, 18);

Result: PHP throws an Error stating that argument #1 ($price) could not be passed by reference. A literal 500.0 is not a variable, so there is no place to store the new value.

Passing a Function Result to a Built-in Reference Parameter

<?php
$lastPart = end(explode(',', 'red,green,blue'));
echo $lastPart;

Output

PHP Notice:  Only variables should be passed by reference in /path/script.php on line 2
blue

end() takes its array by reference (it moves the array's internal pointer), but explode(...) returns a temporary value. PHP still returns the right answer but warns about it. Store the result in a variable first:

<?php
$parts = explode(',', 'red,green,blue');
echo end($parts);

Output

blue

Modifying Arrays in Place

A common use of references is updating an array passed by the caller:

<?php
function addToCart(array &$cart, string $item, int $quantity = 1): void
{
    $cart[$item] = ($cart[$item] ?? 0) + $quantity;
}

$cart = [];

addToCart($cart, 'Pen', 2);
addToCart($cart, 'Notebook');
addToCart($cart, 'Pen');

print_r($cart);

Output

Array
(
    [Pen] => 3
    [Notebook] => 1
)

Each call modifies the caller's $cart directly. $cart[$item] ?? 0 starts the quantity at 0 for new items.

The Alternative: Return a New Array

<?php
function withItem(array $cart, string $item, int $quantity = 1): array
{
    $cart[$item] = ($cart[$item] ?? 0) + $quantity;
    return $cart;
}

$cart = [];
$cart = withItem($cart, 'Pen', 2);
$cart = withItem($cart, 'Notebook');
$cart = withItem($cart, 'Pen');

print_r($cart);

The output is identical. The returning version makes the change visible at the call site ($cart = ...), whereas addToCart($cart, ...) hides the fact that $cart is modified. That visibility is why many developers prefer returning values.


Returning Several Values Without References

References are sometimes used to "return" multiple values. An array with destructuring is usually clearer:

<?php
function splitName(string $fullName): array
{
    $parts = explode(' ', trim($fullName), 2);

    return [$parts[0], $parts[1] ?? ''];
}

[$first, $last] = splitName('Priya Sharma');

echo "$last, $first\n";

Output

Sharma, Priya

The function's signature shows exactly what it produces, and the caller chooses the variable names.


References and Objects

Objects are passed as handles, so a function can change an object's properties without & (see Function Arguments). The & matters only when the function replaces the whole object:

<?php
function replaceWithoutReference(stdClass $user): void
{
    $user = new stdClass();
    $user->name = 'Replaced';
}

function replaceWithReference(stdClass &$user): void
{
    $user = new stdClass();
    $user->name = 'Replaced';
}

$a = new stdClass();
$a->name = 'Original';
replaceWithoutReference($a);
echo $a->name . "\n";

$b = new stdClass();
$b->name = 'Original';
replaceWithReference($b);
echo $b->name . "\n";

Output

Original
Replaced
  • Without &, assigning a new object to $user only changes the function's local copy of the handle; the caller still has the original object.
  • With &, $user is the caller's variable, so it now holds the new object.

Performance Myth

It is sometimes assumed that passing large arrays by reference is faster. In modern PHP, this is generally not true:

  • PHP uses copy-on-write: passing an array by value does not copy it. A copy is made only if the function modifies the array.
  • References can even prevent some internal optimizations.

Use references when you intend to modify the caller's variable — not as a performance trick.


Common Mistakes

Unexpected Side Effects

Effect: A caller's variable changes without any visible assignment at the call site, which makes bugs hard to trace.

Fix: Prefer returning new values; use references only when modifying in place is the clear intent, and name functions accordingly (sortProducts(), addToCart()).

Passing Literals or Function Results

Effect: An Error for user-defined functions, or a "Only variables should be passed by reference" notice for built-ins.

Fix: Store the value in a variable first.

Forgetting the & in the Declaration

Effect: The function silently works on a copy, and the caller's variable is not updated.

Fix: Add & to the parameter, or return the value and assign it.

Leftover References in foreach

Effect: After foreach ($items as &$item), the variable still references the last element and can overwrite it later.

Fix: unset($item); after the loop (see Foreach Loop).


Best Practices

  • Default to pass-by-value and return results.
  • Use references when a function's purpose is to modify its argument in place (as sort() does) or when a built-in API requires it.
  • Make reference usage obvious through function names and documentation.
  • Return arrays (with destructuring) instead of using several output parameters.
  • Do not use references for performance; copy-on-write already avoids unnecessary copies.

Official reference: https://www.php.net/manual/en/functions.arguments.php#functions.arguments.by-reference

0 Comments

Reviewed before they appear

No comments yet.

PHP
PHP Home PHP Switch PHP Match Alternative Syntax PHP Loops While Loop Do While Loop For Loop Foreach Loop Nested Loops Break Statement PHP Home PHP Intro PHP Install PHP Built-in Web Server PHP Syntax PHP Tags PHP and HTML PHP Comments PHP Multiline Comments PHP Variables Variables Scope PHP Casting Logical Operators Null Coalescing Operator Spaceship Operator Operator Precedence Continue Statement Modify Strings PHP If...Else...Elseif PHP If Modify Strings PHP If Operators PHP Functions Concatenate Strings PHP If...Else Slicing Strings User-defined Functions Slicing Strings PHP Shorthand if Escape Characters Default Argument Values PHP Nested if Pass by Reference String Interpolation Named Arguments PHP File Upload Variadic Functions Return Values Search in Strings Multibyte Strings Type Declarations in Functions PHP Numbers PHP Math PHP Floats PHP Random Numbers PHP Constants PHP Properties PHP Methods PHP Constructor Constructor Property Promotion PHP Cookies PHP Destructor PHP Access Modifiers Readonly Properties PHP Sessions PHP Inheritance Method Overriding PHP Filters The final Keyword CSRF Protection PHP Filters Advanced Session Security Secure Cookies PHP Magic Constants File Upload Security PHP Callback Functions PHP Operators Filesystem Security PHP JSON Arithmetic Operators Error Reporting in Production Hiding PHP Assignment Operators PHP Configuration (php.ini) Comparison Operators PHP Command Line (CLI) PHP Exceptions Increment / Decrement Operators Migrating to PHP 8 PHP Form Validation PHP Form Required PHP Form URL/E-mail Error Handling Form Input Sanitizing Escaping Output (htmlspecialchars) Custom Error Handler Checkbox, Radio and Select Inputs Sticky Forms PHP Form Complete PHP Date and Time Date Formatting
Ask about this post
AI Ask about this post

Ask questions about Pass by Reference and get answers drawn from it.

Signed-in readers only.