Signatur
Beschreibung
ArrayAccess ist ein eingebautes PHP-Interface, das vier Methoden vorschreibt. Implementiert eine Klasse dieses Interface, können ihre Instanzen mit der gewohnten Array-Schreibweise ($obj['key'], isset($obj['key']), unset($obj['key'])) verwendet werden, ohne ein echtes Array zu sein.
Das Interface eignet sich hervorragend für Datenzugriffs-Klassen, Konfigurations-Container oder Collections, die eine benutzerfreundliche, vertraute API bieten sollen. Frameworks wie Symfony oder Laravel nutzen ArrayAccess intensiv, etwa für Request-Objekte oder den Service-Container.
Die vier Pflichtmethoden sind: offsetExists() (entspricht isset()), offsetGet() (Lesezugriff), offsetSet() (Schreibzugriff) und offsetUnset() (entspricht unset()). Sie müssen in der Klasse vollständig implementiert werden, auch wenn einzelne Operationen nicht unterstützt werden sollen (dann ggf. eine Exception werfen).
ArrayAccess lässt sich gut mit Countable und Iterator kombinieren, um ein Objekt zu schaffen, das sich nahezu vollständig wie ein Array verhält, aber die Vorteile objektorientierter Typsicherheit und Kapselung bietet.
Beispiele
Einfacher Konfigurations-Container mit ArrayAccess
<?php
class Config implements ArrayAccess
{
private array $data = [];
public function offsetExists(mixed $offset): bool
{
return isset($this->data[$offset]);
}
public function offsetGet(mixed $offset): mixed
{
return $this->data[$offset] ?? null;
}
public function offsetSet(mixed $offset, mixed $value): void
{
if ($offset === null) {
$this->data[] = $value;
} else {
$this->data[$offset] = $value;
}
}
public function offsetUnset(mixed $offset): void
{
unset($this->data[$offset]);
}
}
$config = new Config();
$config['db_host'] = 'localhost';
$config['db_port'] = 3306;
echo $config['db_host'] . PHP_EOL; // localhost
echo isset($config['db_port']) ? 'Port gesetzt' : 'kein Port';
unset($config['db_port']);
echo PHP_EOL . (isset($config['db_port']) ? 'Port gesetzt' : 'Port nicht mehr gesetzt');
Read-only-Objekt: Schreibzugriff per Exception verbieten
<?php
class ReadOnlyMap implements ArrayAccess
{
public function __construct(private array $data) {}
public function offsetExists(mixed $offset): bool
{
return array_key_exists($offset, $this->data);
}
public function offsetGet(mixed $offset): mixed
{
if (!$this->offsetExists($offset)) {
throw new OutOfBoundsException("Schlüssel '$offset' nicht gefunden.");
}
return $this->data[$offset];
}
public function offsetSet(mixed $offset, mixed $value): void
{
throw new LogicException('Diese Map ist schreibgeschützt.');
}
public function offsetUnset(mixed $offset): void
{
throw new LogicException('Diese Map ist schreibgeschützt.');
}
}
$map = new ReadOnlyMap(['sprache' => 'PHP', 'version' => '8.3']);
echo $map['sprache'] . ' ' . $map['version'] . PHP_EOL;
try {
$map['neu'] = 'Wert';
} catch (LogicException $e) {
echo 'Fehler: ' . $e->getMessage();
}
// Wichtig · Fallstricke
Kein echtes Array: Objekte, die ArrayAccess implementieren, sind keine Arrays. Funktionen wie array_map(), array_keys() etc. funktionieren nicht direkt darauf. Um Iterierbarkeit zu erhalten, sollte zusätzlich Iterator oder IteratorAggregate implementiert werden.
Typangaben ab PHP 8.1: Ab PHP 8.1 sollten die Parameter von offsetGet, offsetSet usw. mit mixed typisiert werden. Abweichende Typen können zu Kompatibilitätswarnungen führen.
offsetGet per Referenz: Wenn offsetGet() per Referenz (&) zurückgeben soll (etwa für $obj['key'][] = 'wert'), muss die Methode explizit & in der Signatur tragen. Dies ist ein häufiger Fallstrick bei verschachtelten Schreibzugriffen.