Indirect modification of overloaded element of %s has no effect

Description

The variable $object is an object. Since it implements the ArrayAccess interface, it may also use the array syntax, for example with the brackets and index.

While the syntax makes $object looks like an array, not all operations are available. It is possible to get an index’s value, or to give it a new value; but it is not possible to use the increment or decrement operators : those are both a get and a set, and this is not supported by the ArrayAccess interface.

Here, the notion of ‘overloaded’ applies to the object properties: they are not data containers, as usual, but replaced (overloaded) with method calls.

There are different variations of that situation : for example, an append on the value at an index is not possible either. In fact, the interface returns a value (not a reference), and the append applies to a value, that is not linked the orginal array.

Besides the ArrayAccess, there are several native PHP classes that triggers these warning: ArrayObject, ArrayIterator, PDORow or ArrayAccessImpl.

Example

<?php
class ObjectOne implements ArrayAccess {
    function offsetGet($index): mixed {
        echo __METHOD__ . "($index)\n";
        return 2;
    }

    function offsetExists($index): bool { return true; /**/ }
    function offsetSet($index, $newval): void { /**/ }
    function offsetUnset($index): void { /**/ }
}

$object = new ObjectOne;

$object[2]++;
$object[2][3] = 2;

?>

Solutions

  • Use an actual array to handle those edge cases.

  • Write the ObjectOne class to handle these operation with a method call.