Hello, internals! Recently I was implementing some collections and realized that I cannot use `ArrayAccess` for immutable collections without throwing `BadMethodCallException` in `offsetSet` and `offsetUnset`. I also cannot have an `interface ReadonlyCollection extends ArrayAccess`, because `offsetSet` and `offsetUnset` are mutators and have `TValue` in a contravariant position.
Here's the idea: let's extract `ArrayAccess::offsetExists` and `ArrayAccess::offsetGet` methods into a separate `ArrayAccessRead` interface (name can be different) and allow read operations `$exists = isset($object['key'])` and `$value = $object['key']` for objects of classes that implement this interface. `ArrayAccess` will then extend `ArrayAccessRead` and add the remaining 2 methods. Looks like this change should not break backward compatibility. ``` interface ArrayAccessRead { public function offsetExists(mixed $offset): bool; public function offsetGet(mixed $offset): mixed; } interface ArrayAccess extends ArrayAccessRead { public function offsetSet(mixed $offset, mixed $value): void; public function offsetUnset(mixed $offset): void; } // then interfaces of the doctrine/collections package might look like this: namespace Doctrine\Common\Collections; interface ReadableCollection extends Countable, IteratorAggregate, ArrayAccessRead {} interface Collection extends ReadableCollection, ArrayAccess {} ``` -- Regards, Valentin Udaltsov