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