Deep Copying an Array in PHP: Myths and Reality
\n\nImagine this situation: you are writing a script that processes data from a database. You get an array of users, do something with it, and then suddenly discover that the original data has changed. Sound familiar? If you work with PHP, this problem can catch even an experienced developer off guard.
\n\nThe question “Is there a function to make a copy of a PHP array to another?” on Stack Overflow has garnered tens of thousands of views. And this is no coincidence. At first glance, copying arrays in PHP seems like a trivial task. But the devil, as always, is in the details.
\n\nIn this article, we will break down all possible ways to copy an array in PHP: from simple assignment to working with multidimensional structures. You will learn when PHP creates a real copy and when it only creates a reference to the data. Let's go!
\n\nDirect Assignment: The First Surprise
\n\nThe most intuitive way is to simply assign the array to another variable:
\n\n$original = ['apple', 'banana', 'cherry'];\n$copy = $original;\n$copy[0] = 'mango';\n\nprint_r($original);\n// Array ( [0] => apple [1] => banana [2] => cherry )\nprint_r($copy);\n// Array ( [0] => mango [1] => banana [2] => cherry )\n\nSurprisingly, this works! In PHP, arrays are value types, not reference types. When you assign an array to another variable, PHP creates a shallow copy with copy-on-write.
\n\nIn simple terms: as long as you don't modify either array, they point to the same data in memory. As soon as you try to change an element in one of the variables, PHP allocates new memory and copies the data. This is very efficient and requires no extra action.
\n\nConclusion: For simple one-dimensional arrays, direct assignment is a full copy.
\n\nThe Pitfall: Objects Inside the Array
\n\nNow imagine that the array contains objects:
\n\nclass User {\n public $name;\n public function __construct($name) {\n $this->name = $name;\n }\n}\n\n$original = [new User('Alice'), new User('Bob')];\n$copy = $original;\n$copy[0]->name = 'Charlie';\n\nprint_r($original[0]->name); // Charlie\n\nThere's the surprise! The shallow copy copied a reference to the object, not the object itself. By modifying the object in the copy, you modify it in the original. Objects require a different approach.
\n\nThe array_merge() Function: Non-Obvious Nuances
\n\nYou often see advice to use array_merge() to copy an array:
$original = [1, 2, 3];\n$copy = array_merge([], $original);\n$copy[0] = 100;\n\nprint_r($original); // [1, 2, 3]\n\nYes, this works. But there is an important nuance: array_merge() resets numeric keys and re-indexes them starting from zero. If your keys are strings, everything is fine. But if they are numeric, be prepared for surprises:
$original = ['a' => 1, 2 => 'two', 5 => 'five'];\n$copy = array_merge([], $original);\n\nprint_r($copy);\n// Array ( [a] => 1 [0] => two [1] => five )\n\nSee? Keys 2 and 5 turned into 0 and 1. This can break logic if the order of keys is important.
\n\nConclusion: array_merge() is only suitable for copying arrays with string keys or when re-indexing is not a concern.
Copying with a Loop: Manual Control
\n\nThe most reliable, but also the most verbose method, is to iterate through the array with a loop:
\n\n$original = ['x' => 10, 'y' => 20];\n$copy = [];\n\nforeach ($original as $key => $value) {\n $copy[$key] = $value;\n}\n\n$copy['x'] = 100;\nprint_r($original['x']); // 10\n\nFor simple arrays, this is overkill. But if you need to make a deep copy, then without recur