codeisart.

PHP

Создание объектно-ориентированного аналога массива в PHP. Часть 2

ArrayAccess делает синтаксис удобнее, но не заменяет документированный контракт. Запись через квадратные скобки работает как у массива; строгий add остаётся способом…

В этой статье

Интерфейсы и снимок перебора

ArrayAccess делает синтаксис удобнее, но не заменяет документированный контракт. Запись через квадратные скобки работает как у массива; строгий add остаётся способом запретить дубликаты. Countable возвращает число элементов, включая null. IteratorAggregate отдаёт отдельный снимок структуры.

    public function offsetExists(mixed $offset): bool
    {
        return $this->has($offset) && $this->get($offset) !== null;
    }

    public function offsetGet(mixed $offset): mixed
    {
        return $this->get($offset);
    }

    public function offsetSet(mixed $offset, mixed $value): void
    {
        if ($offset === null) {
            $this->append($value);
        } elseif ($this->has($offset)) {
            $this->replace($value, $offset);
        } else {
            $this->add($value, $offset);
        }
    }

    public function offsetUnset(mixed $offset): void
    {
        $this->remove($offset);
    }

    public function count(): int
    {
        return count($this->items);
    }

    public function getIterator(): Traversable
    {
        return new ArrayIterator($this->items);
    }

Поверхностная копия: что именно независимо

Удаление ключа или добавление нового элемента в коллекцию не меняет ранее созданный итератор. Но Client — изменяемый объект, и ссылка на него общая. clone коллекции тоже не клонирует вложенные объекты: если нужна независимость их полей, потребуется отдельная политика глубокого копирования.

$copy = clone $clients;
$copy->add(new Client('Саша'), 'alexander'); // Новый ключ только в копии.
$copy['ivan']->name = 'Иван'; // Тот же Client меняется и в оригинале.

Проверки границ

Тесты отдельно проверяют 0/"0", пустой ключ, null-значение, отклонение null-ключа, дубликаты, вставку/замену, порядок перебора, count, неверные типы ключей и поверхностное клонирование. empty не используется как проверка наличия.