In PHP, if you assign an array to another variable or pass it to a function and modify that copy, what happens to the original?
answer
- arrays are values, not handles
- $b = $a then writing $b leaves $a
- functions get a copy unless &$param
- objects inside stay shared handles
- reference elements survive the copy
basics
~20 sNothing: PHP arrays are values, so assignment and by-value parameters give an independent copy, and changing it leaves the original intact. Objects stored inside are handles, so both copies still point to the same objects.
solid answer
~50 sPHP arrays have **value semantics**. `$b = $a;` and passing `$a` to a normal parameter both give the receiver its own array; `$b[] = 4` or `$b['k'] = 'x'` never shows up in `$a`. To let a function modify the caller's array you must declare the parameter by reference (`array &$items`) or return the new array. The engine does not duplicate the data at the moment of assignment; it shares it until one side writes, so copying is cheap in practice. Two things are not deep-copied: **objects** stored in the array are handles, so `$b[0]->status = 'x'` is visible through `$a[0]`; and an element that is a PHP **reference** stays shared between the copies. Unlike languages where arrays or lists are reference types shared by every variable, a PHP array behaves like a string or an int.
code
php · 20 lines<?php
function addDefault(array $cfg): void
{
$cfg['debug'] = false; // changes only the local copy
}
$cfg = ['env' => 'prod'];
addDefault($cfg);
var_dump(array_key_exists('debug', $cfg)); // bool(false)
final class Order
{
public function __construct(public string $status) {}
}
$orders = [new Order('new')];
$copy = $orders;
$copy[] = new Order('new'); // original still has one element
$copy[0]->status = 'paid'; // same object behind both arrays
echo count($orders), ' ', $orders[0]->status; // 1 paidgo deeper
Recall that arrays are copied on assignment and when passed to a normal parameter, so changes to the copy never reach the original.
Explain returning versus &-parameters, why read-only passing is cheap, and why objects inside an array stay shared after the copy.
Spot bugs from shared objects and leftover references in copied arrays, and avoid needless &-parameters added for imagined performance gains.
Set conventions for mutability at API boundaries, preferring returned arrays or immutable value objects over in-place mutation across modules.
## Arrays are values In PHP an array behaves like a number or a string, not like an object. Assigning it or passing it to a function hands over a **value**, and the receiver can change its own array without affecting anyone else's: ```php $a = [1, 2, 3]; $b = $a; $b[] = 4; // $a is still [1, 2, 3] ``` The same holds at function boundaries. A parameter declared `array $items` receives a copy; appending, removing or overwriting elements inside the function changes only that copy. ## Getting changes back to the caller There are two idiomatic ways to let a function change an array the caller holds: 1. **Return it.** `function withDefaults(array $cfg): array { $cfg['debug'] ??= false; return $cfg; }` and the caller writes `$cfg = withDefaults($cfg);`. This is the usual choice in modern code because the data flow is visible at the call site. 2. **Take it by reference.** `function addDefaults(array &$cfg): void` lets the function write into the caller's variable directly. Several built-ins work this way, such as `sort()` and `array_push()`, which is why they return a status or count instead of the new array. ## Cheap copies Value semantics do not mean every assignment duplicates the data. The engine shares one array between variables and copies it only when one of them is about to be written, a technique described elsewhere as copy-on-write. For interview purposes the consequences are what matter: - passing a large array to a function that only reads it costs almost nothing; - the first write to a shared array triggers a full copy, which can be expensive for very large arrays inside loops; - taking a parameter by reference *to avoid a copy* is usually pointless and makes the code harder to reason about. ## What is not copied Value semantics apply to the array's own slots. What sits in those slots follows its own rules: | Element type | After `$b = $a` and a write through `$b` | |---|---| | scalar (int, string, bool, float) | independent; `$a` unchanged | | nested array | independent; nested arrays are values too | | object | **shared**: both arrays hold handles to the same object | | element bound by reference (`$x = &$a[0]` earlier) | **shared**: the reference is preserved in the copy | The object row is the most common surprise. Copying an array of entity objects and then calling setters on the copy changes the objects the original array points to, because only the handles were copied. To get independent objects you must `clone` each one. The reference row is rarer but nastier. The PHP manual warns that references inside arrays are preserved on normal assignment and when passing an array by value. A leftover reference, for example from an earlier `foreach ($a as &$v)` loop, can make a supposedly independent copy change the original. ## Contrast with reference-type collections In languages where arrays or lists are reference types, `b = a` makes two names for one collection, and a change through either is visible through both; getting an independent copy needs an explicit copy call. PHP chose the opposite default for arrays, while its objects follow the handle model. Interviewers ask this to see whether a candidate carries the other model into PHP code, for example expecting a function to fill an array passed to it without `&` or a return value. ## Practical checklist - Expect assignment and by-value parameters to isolate array changes. - Return modified arrays, or declare `&` deliberately when mutation in place is the point. - Remember that objects inside are shared, and clone them when you need independence. - `unset($v)` after any `foreach` by reference, so no reference lingers inside the array.
- Should you pass a large array by reference to avoid copying it?Usually not. A by-value array is shared with the caller until one side writes, so a function that only reads it copies nothing. Declaring `&` just to save memory adds mutation risk without a real gain; use it only when changing the caller's array is the actual purpose.
- How can a leftover reference make a copied array change the original?An element that is a PHP reference, for example left behind by `foreach ($a as &$v)` without `unset($v)`, stays a reference after `$b = $a`. Writing through that element in either array, or through `$v`, then changes the value both arrays see.
saying these in an interview costs you the question
- Arrays are passed to functions by reference by default.
- Assigning an array to a new variable duplicates its memory immediately.
- Copying an array also clones the objects stored inside it.
- A function can fill a caller's array parameter without & or a return value.
- Passing big arrays by reference is the standard way to save memory.