ZetCode

PHP Copy by Value vs Reference

last modified May 16, 2025

This tutorial explains how PHP handles copy by value and copy by reference, affecting variable assignment and parameter passing. Understanding these concepts is crucial for writing efficient PHP code, especially when working with large data structures.

Value Copying in PHP

By default, PHP uses copy-on-write semantics for variable assignment. This means variables are copied by value, but the actual copy only happens when a variable is modified.

Characteristic Copy by Value Copy by Reference
Default Behavior Yes (copy-on-write) No (must use & operator)
Memory Usage Efficient until modification Shared until unset
Examples $b = $a $b = &$a

Copy by Value Example

PHP's default copy behavior creates independent copies when variables are modified, but uses copy-on-write to optimize memory usage.

main.php
<?php

declare(strict_types=1);

// Simple types are always copied by value
$a = 10;
$b = $a; // Copy by value

echo "Original: a = $a, b = $b\n";
$b = 20; // Doesn't affect $a
echo "After change: a = $a, b = $b\n";

// Arrays use copy-on-write
$arr1 = [1, 2, 3];
$arr2 = $arr1; // Copy-on-write (no actual copy yet)

$arr2[0] = 99; // Now makes a copy
echo "arr1[0] = {$arr1[0]}, arr2[0] = {$arr2[0]}\n";

In the example, modifying $b does not affect $a because they are independent copies. However, modifying $arr2 creates a new copy of the array, leaving $arr1 unchanged. This is due to PHP's copy-on-write optimization, which avoids unnecessary memory usage until a modification is made.

$ php main.php
Original: a = 10, b = 10
After change: a = 10, b = 20
arr1[0] = 1, arr2[0] = 99

Strings in PHP: Copy by Value

Strings in PHP are scalar types and are always copied by value. Assigning one string variable to another creates an independent copy. Modifying one string does not affect the other, as each variable holds its own value.

main.php
<?php

declare(strict_types=1);

$s1 = "hello";
$s2 = $s1; // Copy by value

echo "Original: s1 = $s1, s2 = $s2\n";
$s2 = "there"; // s1 is not affected

echo "After change: s1 = $s1, s2 = $s2\n";

In this example, $s1 and $s2 are independent. Changing $s2 does not affect $s1 because strings are always copied by value in PHP.

$ php main.php
Original: s1 = hello, s2 = hello
After change: s1 = hello, s2 = there

Objects and References

Since PHP 5, objects are handled by reference by default. Assigning an object to a new variable doesn't create a copy, but rather creates another reference to the same object.

main.php
<?php

declare(strict_types=1);

class Person {
    public $name;
    
    public function __construct($name) {
        $this->name = $name;
    }
}

$person1 = new Person('Alice');
$person2 = $person1; // Both reference the same object

echo "Original: person1->name = {$person1->name}, ";
echo "person2->name = {$person2->name}\n";

$person2->name = 'Bob'; // Affects both references
echo "After change: person1->name = {$person1->name}, ";
echo "person2->name = {$person2->name}\n";

// To create a true copy, use clone
$person3 = clone $person1;
$person3->name = 'Charlie';
echo "After clone: person1->name = {$person1->name}, ";
echo "person3->name = {$person3->name}\n";

In the example, modifying $person2 also affects $person1 because they reference the same object. However, using clone creates a new object, allowing independent modifications.

$ php main.php
Original: person1->name = Alice, person2->name = Alice
After change: person1->name = Bob, person2->name = Bob
After clone: person1->name = Bob, person3->name = Charlie

Explicit References

PHP allows creating explicit references using the & operator. This creates an alias where both variables point to the same data.

main.php
<?php

declare(strict_types=1);

$a = 10;
$b = &$a; // $b is now a reference to $a

echo "Original: a = $a, b = $b\n";
$b = 20; // Changes both $a and $b
echo "After change: a = $a, b = $b\n";

// Works with arrays too
$arr1 = [1, 2, 3];
$arr2 = &$arr1;
$arr2[0] = 99;
echo "arr1[0] = {$arr1[0]}, arr2[0] = {$arr2[0]}\n";

// To break a reference
unset($b); // Removes the reference, $a keeps its value

In this example, modifying $b also affects $a because they are references to the same value. The same applies to arrays.

$ php main.php
Original: a = 10, b = 10
After change: a = 20, b = 20
arr1[0] = 99, arr2[0] = 99

Parameter Passing

PHP supports both pass-by-value and pass-by-reference for function parameters. By default, parameters are passed by value, but references can be specified.

main.php
<?php

declare(strict_types=1);

// Pass by value (default)
function modifyValue($x) {
    $x = 100;
    echo "Inside function: x = $x\n";
}

$a = 10;
modifyValue($a);
echo "After function: a = $a\n";

// Pass by reference
function modifyReference(&$x) {
    $x = 100;
    echo "Inside function: x = $x\n";
}

$b = 10;
modifyReference($b);
echo "After function: b = $b\n";

// Objects are always passed by reference
function modifyObject($obj) {
    $obj->value = 100;
}

$object = new stdClass();
$object->value = 10;
modifyObject($object);
echo "Object value: {$object->value}\n";

In the example, the first function modifies a copy of the variable, while the second function modifies the original variable. The object is passed by reference, so its property is modified directly.

$ php main.php
Inside function: x = 100
After function: a = 10
Inside function: x = 100
After function: b = 100
Object value: 100

Returning References

PHP functions can return references, but this should be used sparingly as it can lead to confusing code and maintenance issues.

main.php
<?php

declare(strict_types=1);

class Container {
    private $data = [];
    
    public function &getDataReference() {
        return $this->data;
    }
    
    public function getDataCopy() {
        return $this->data;
    }
}

$container = new Container();
$ref = &$container->getDataReference();
$ref['key'] = 'value'; // Modifies the container's private data

$copy = $container->getDataCopy();
$copy['key'] = 'new value'; // Doesn't affect container

var_dump($container->getDataCopy());

In this example, the getDataReference method returns a reference to the container's private data, allowing modifications to affect the original data. The getDataCopy method returns a copy, so modifications do not affect the original data.

$ php main.php
array(1) {
  ["key"]=>
  string(5) "value"
}

Summary and Best Practices

This tutorial covered PHP's approach to value and reference copying, including assignment behavior, parameter passing, and object handling.

Source

PHP References

PHP Objects and References

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all PHP tutorials.