The Art of Immutable Array Updates Using Functional PHP
To achieve immutable array updates in PHP, it must be done by creating a new array instead of modifying the original array. 1. Avoid directly modifying the array elements. You should use array_merge() or manually copy to generate a new array; 2. Use array_merge() to perform concise immutable updates, keeping the original array unchanged and supporting the addition of new keys; 3. Use pure functions such as recursive setIn() for nested arrays to ensure that there are no side effects when the deep structure is updated; 4. Combine functional tools such as array_map and array_filter to achieve side effects without side effects; 5. Strengthen immutability through conventions, such as treating the input array as read-only, returning a new array, encapsulating data using PHP 8.2 readonly class or DTO of PHP 8.2. This approach improves the predictability, maintainability and testability of the code, ultimately achieving safer state management.
Immutable array updates in PHP might sound like a concept borrowed from functional programming languages like Haskell or Elm, but you can apply the same principles effectively even in PHP—especially as the language matures with features supporting functional patterns.

The core idea is simple: instead of modifying an array in place, you create a new array that includes the desired changes, leaving the original untouched. This leads to more predictable code, easier debugging, and fewer side effects—especially valuable in larger applications or when working with state in a functional style.
Here's how to master immutable array updates in PHP using functional techniques.

1. Avoid Modifying Arrays In Place
In traditional PHP, you might do something like:
$user = ['name' => 'Alice', 'age' => 30]; $user['age'] = 31; // Mutation!
This mutates the original array. Instead, create a new version:

$user = ['name' => 'Alice', 'age' => 30]; $newUser = ['name' => $user['name'], 'age' => $user['age'] 1];
Now $user
remains unchanged, and $newUser
reflects the update.
But manually copying keys gets tedious. Use the spread-like behavior of
or array_merge()
.
2. Use array_merge()
for Clean Immutable Updates
array_merge()
is your go-to tool for creating updated copies:
$user = ['name' => 'Alice', 'age' => 30]; $updatedUser = array_merge($user, ['age' => 31]);
This returns a new array. The original $user
is untouched.
You can also add new keys:
$extendedUser = array_merge($user, ['active' => true]);
Important: array_merge()
only works reasonably with indexed or associated arrays, not complex nested structures unless handled recursively.
3. Handle Nested Updates with Pure Functions
For nested arrays, immutability requires deeper care. Don't do this:
$data['user']['profile']['theme'] = 'dark'; // Mutation!
Instead, build a pure function to return a new structure:
function withUpdatedTheme(array $data, string $theme): array { return array_merge($data, [ 'user' => array_merge($data['user'], [ 'profile' => array_merge($data['user']['profile'], [ 'theme' => $theme ]) ]) ]); }
Usage:
$newData = withUpdatedTheme($data, 'dark');
Now $data
is preserved, and changes are encapsulated in a reusable, testable function.
For deeply nested data, consider writing a generic setIn()
function:
function setIn(array $array, array $path, $value): array { $result = $array; $cursor = &$result; foreach ($path as $key) { if (!is_array($cursor)) { $cursor = []; } $cursor = &$cursor[$key]; } $cursor = $value; return $result; }
Wait—this uses references and mutates $result
. Not pure.
Here's a truly immutable version:
function setIn(array $array, array $path, $value): array { if (empty($path)) { return $array; } $key = array_shift($path); if (!empty($path)) { $nested = $array[$key] ?? []; if (!is_array($nested)) { $nested = []; } $array[$key] = setIn($nested, $path, $value); } else { $array[$key] = $value; } return $array; }
Now you can do:
$newData = setIn($data, ['user', 'profile', 'theme'], 'dark');
And $data
remains unchanged.
4. Combine with Functional Helpers
To make this style more expressive, pair immutable updates with functional helpers.
For example, map over arrays without mutation:
$users = [['name' => 'Alice', 'age' => 30], ['name' => 'Bob', 'age' => 25]]; $usersAgedUp = array_map( fn($user) => array_merge($user, ['age' => $user['age'] 1]), $users );
Or filter:
$activeUsers = array_filter($users, fn($user) => $user['active'] ?? false);
These don't alter the original $users
array—pure and predictable.
5. Embrace Immutability by Convention
PHP doesn't enforce immutability, so discipline matters. Tips:
- Treat arrays passed into functions as read-only.
- Return new arrays instead of modifying inputs.
- Use
readonly
classes (PHP 8.2) when modeling data structures. - Consider using value objects or DTOs for complex data.
Example with a readonly class:
readonly class User { public function __construct( public string $name, public int $age ) {} } function withAgeIncreased(User $user, int $by = 1): User { return new User($user->name, $user->age $by); }
Now immutability is enforced at the object level.
Immutable array updates in PHP aren't automatic, but with array_merge()
, pure functions, and functional thinking, you can write safer, more maintained code. It's not about copying everything—it's about control, clarity, and avoiding unintended consequences.
Basically, if you treat data as if it can't be changed, you'll write better PHP.
The above is the detailed content of The Art of Immutable Array Updates Using Functional PHP. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Use array_merge() to simply overwrite the value of the second array to update the original array; 2. Use the union operator ( ) to retain the original array value and add only missing keys (suitable for setting the default value); 3. Fine-grained control can be achieved through foreach combined with conditions, such as updating only non-null values; 4. For nested arrays, array_replace_recursive() should be used to achieve deep updates; 5. When updating, array_key_exists() or isset() should always be used to safely check the existence of the keys to avoid errors; these methods cover the main scenarios of updating arrays based on another array in PHP, and appropriate methods should be selected according to the data structure and logic to ensure operation

array_walk is a powerful function in PHP for modifying array elements in place. It is suitable for scenarios where complex transformations are required based on key names, nested structures, or external states. 1. It passes arrays and elements through references and directly modifys the original array; 2. The callback function can access keys and values and supports the third parameter passing context; 3. It can process multi-dimensional arrays in combination with recursion; 4. It is suitable for batch modification of object properties; 5. It does not return a new array, and its performance is better than array_map but is not suitable for scenarios where the original array needs to be retained. When used correctly, it performs efficiently and has a clean code in handling context-sensitive or recursive data transformations.

Tooptimizelarge-scalearrayupdates:1.Mutatearraysinplaceinsteadofcreatingcopiesusingspreadorconcattoreducememoryusage;2.Batchupdatestominimizefunctioncalloverhead,pre-allocatearrayswhensizeisknown,andchunklargeinsertionstoavoidcallstacklimits;3.Usetyp

Dynamicarraysallowruntimemodificationbyaddingorupdatingelements,withbestpracticesensuringefficiencyandsafety.1)Usepush/appendtoaddelementsattheendforoptimalperformance.2)Avoidunshift/insertormiddleinsertionswhenpossible,astheyrequireshiftingelementsa

Userecursivefunctionstosafelytraverseandupdatenestedarrayswithunknowndepthbycreatingmissingkeysasneeded.2.Leveragearrayreferenceswiththe&operatortodirectlymodifyoriginalarrayelementswithouttriggeringcostlycopiesduringdeeptraversal.3.Implementdotn

To realize the update of immutable arrays in PHP, it must be done by creating a new array instead of modifying the original array. 1. Avoid directly modifying the array elements. You should use array_merge() or manually copy to generate a new array; 2. Use array_merge() to perform concise immutable updates, keeping the original array unchanged and supporting the addition of new keys; 3. Use pure functions such as recursive setIn() for nested arrays to ensure that there are no side effects when the deep structure is updated; 4. Combined with functional tools such as array_map and array_filter to achieve data processing without side effects; 5. Strengthen immutability through conventions, such as treating the input array as read-only, returning a new array, and using reado in PHP8.2

ArraysofobjectsinPHPcontainclassinstances,allowingdirectpropertyormethod-basedmodifications;2.Updatepropertiesusingforeachloopssinceobjectsarepassedbyreference,orusesettersforencapsulatedproperties;3.Filterobjectswitharray_filter()tocreatesubsetsbase

Use PHP references to achieve in-situ updates of arrays, avoiding copy overhead and improving performance. 1. Use the & operator to create references so that the variable points to the same data, and the modification is reflected to the original array; 2. When processing nested arrays, obtain deep element references through &, and directly modify them without reassigning; 3. Use &$item in the foreach loop to modify the original array elements, but unset($item) must be unset($item) after the loop to prevent subsequent side effects; 4. You can write functions to return deep references through dynamic paths, which are suitable for configuration management and other scenarios; 5. Although references are efficient, they should be used with caution to avoid overcomplex code, ensure that the logic is clear and comments are added if necessary. Correct use of references can significantly optimize large sizes
