Ответ
Чтобы объект в PHP мог использоваться как массив (с синтаксисом $obj['key']), он должен реализовывать интерфейс ArrayAccess. Этот интерфейс требует определения четырех методов:
offsetExists($offset): bool— проверяет, существует ли элемент по ключу.offsetGet($offset): mixed— возвращает значение по ключу.offsetSet($offset, $value): void— устанавливает значение по ключу.offsetUnset($offset): void— удаляет элемент по ключу.
Практический пример — коллекция:
class ItemCollection implements ArrayAccess
{
private array $items = [];
public function offsetExists($offset): bool
{
return array_key_exists($offset, $this->items);
}
public function offsetGet($offset): mixed
{
return $this->items[$offset] ?? null;
}
public function offsetSet($offset, $value): void
{
if (is_null($offset)) {
$this->items[] = $value; // Добавление в конец, как $array[]
} else {
$this->items[$offset] = $value;
}
}
public function offsetUnset($offset): void
{
unset($this->items[$offset]);
}
}
// Использование
$cart = new ItemCollection();
$cart['apple'] = 5; // Вызовет offsetSet
$count = $cart['apple']; // Вызовет offsetGet, вернет 5
isset($cart['pear']); // Вызовет offsetExists, вернет false
unset($cart['apple']); // Вызовет offsetUnset
Это мощный инструмент для создания объектов, которые ведут себя как нативные структуры данных.
Ответ 18+ 🔞
Ну ты представляешь, в PHP можно сделать так, чтобы твой объект вёл себя как самый обычный массив, с квадратными скобками и всем таким. Это же ёперный театр какой-то! Но для этого надо, чтобы твой класс реализовал интерфейс ArrayAccess. А это значит, что придётся написать четыре метода, иначе нихуя не получится.
Вот эти четыре стража порядка:
offsetExists($offset): bool— проверяет, есть ли такой ключ, или мы тут воздух сотрясаем.offsetGet($offset): mixed— достаёт значение по ключу, если оно, конечно, есть.offsetSet($offset, $value): void— кладёт значение по ключу. Тут, кстати, есть хитрая жопа: если ключ не указан (как при$array[] = 'value'), то$offsetбудетnull, и надо добавить элемент в конец.offsetUnset($offset): void— просто выкидывает элемент нахуй, как будто его и не было.
Смотри, как это выглядит на практике. Допустим, мы делаем корзину для покупок:
class ItemCollection implements ArrayAccess
{
private array $items = [];
public function offsetExists($offset): bool
{
return array_key_exists($offset, $this->items);
}
public function offsetGet($offset): mixed
{
return $this->items[$offset] ?? null;
}
public function offsetSet($offset, $value): void
{
if (is_null($offset)) {
$this->items[] = $value; // Классическое "добавь в конец"
} else {
$this->items[$offset] = $value;
}
}
public function offsetUnset($offset): void
{
unset($this->items[$offset]);
}
}
// А теперь используем, и волнение ебать какое!
$cart = new ItemCollection();
$cart['apple'] = 5; // Тихо вызовется offsetSet
$count = $cart['apple']; // Тут сработает offsetGet, вернёт 5
isset($cart['pear']); // offsetExists скажет false, груш нет
unset($cart['apple']); // И offsetUnset сотрёт яблоко в порошок
Вот такая магия, чувак. Получается мощнейший инструмент, чтобы заставить объекты прикидываться нативными массивами. Сам от себя охуел, когда впервые разобрался.