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.
- Simple types (
int
,float
,string
,bool
) are always copied by value - Complex types (
array
,object
,resource
) use copy-on-write for value copying - References can be explicitly created using the
&
operator
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.
<?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.
<?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.
<?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.
<?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.
<?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.
<?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
- PHP uses copy-on-write for efficient value copying
- Objects are handled by reference since PHP 5
- Use
&
operator for explicit references - Function parameters are passed by value by default
- Use
clone
to create independent object copies - Avoid returning references unless absolutely necessary
- Understand these behaviors to write memory-efficient PHP code
This tutorial covered PHP's approach to value and reference copying, including assignment behavior, parameter passing, and object handling.
Source
Author
List all PHP tutorials.