Avoid array_walk() Errors on PHP Readonly Array Properties

PHP reports Cannot modify readonly property when a readonly array property is passed directly to array_walk() or array_walk_recursive(). Those functions accept the array by reference, so the call is treated as potentially modifying the property even when the callback only reads values.

Last updated: October 24, 2026.

<?php
final class Variables
{
    public function __construct(private readonly array $values) {}

    public function containsObjects(): bool
    {
        foreach ($this->values as $value) {
            if (is_object($value)) {
                return true;
            }
        }
        return false;
    }

    public function normalizedCopy(): array
    {
        $copy = $this->values;
        array_walk($copy, static function (&$value): void {
            if (is_string($value)) {
                $value = trim($value);
            }
        });
        return $copy;
    }
}

Use foreach when the operation is read-only. If the callback intentionally transforms values, copy the property to a local variable, walk the copy, and return the result without assigning it back to the readonly property.

Why a read-only callback still fails

The PHP manual signature for array_walk() marks its first parameter as array|object &$array. Passing by reference gives the function a modifiable reference to the variable. A readonly property cannot be modified after initialization, and PHP does not inspect the callback to prove that it leaves every value unchanged.

The same reasoning applies to array_walk_recursive(). Adding or removing the callback value reference does not change how the outer array parameter is passed. Suppressing the error or catching it is not a sound solution because the operation was rejected before the intended traversal could complete.

Choose traversal by intent

For inspection, validation, searching, counting, or early exit, a foreach loop is explicit and usually simpler. It can return as soon as a match is found, unlike a complete walk. For transformation, make a local copy or use a function such as array_map() that returns a new array. Remember that PHP arrays are copied on write, so assigning the property to a local variable does not immediately duplicate every element.

PHP 8.1 introduced readonly properties as properties that may be initialized once and then remain unchanged. The detailed readonly properties specification also explains that array mutation through a readonly property is prohibited. Continue with PHP array fundamentals, multidimensional arrays, and sorting arrays in PHP.

Related Web Cheat Sheet guides

Sergey Kornilov

Sergey Kornilov