# 5.5.4 ArrayAccess-Interface

Das ArrayAccess-Interface ermöglicht es uns, auf ein Objekt zuzugreifen, als wäre es ein assoziatives Array. Dies kommt in einigen PHP-Frameworks vor und daher sollten Sie die Schreibweise verstehen.

Anmerkung

PHP-Frameworks werden in der professionellen Programmierung oft genutzt, da diese vorgefertigte Lösungen zu vielen Standardproblemen bieten. Diese Frameworks wie z.B. "Symfony", "Laravel" oder "CodeIgniter" haben umfangreiche Klassenbibliotheken. Welches Framework "das Beste ist", darüber können Profi-Programmierer:innen stundenlang diskutieren und es gibt verschiedene Top-PHP-Framework-Listen (einfach mal in die Suchmaschine eingeben ;-)

Hier soll Ihnen also eine "seltsame Schreibweise" gezeigt werden, die bei der Nutzung eines Frameworks auftreten kann.

Gegeben sei z.B. eine Klasse Content (als beliebiges Beispiel), die wir instanzieren und so z.B. das Objekt `$content` erhalten (siehe Zeile 1). Und wir verwenden das Objekt `$content` als wäre es ein Array (siehe Zeile 2), was natürlich normalerweise zu einer netten Fehlermeldung führt.

    1
    2
    3
    <?php
    $content = new Content();
    $content["title"] = "Mein Hunde-Blog";

Ermöglicht wird diese Schreibweise durch das ArrayAccess-Interface.

Anmerkung

Kurze Wiederholung zum Begriff "Interface": Ein Interface ist eine vollständig abstrakte Klasse, die nur die Methodennamen vorgibt, die in der abgeleiteten Klasse zu implementieren sind. Ein Interface kann nicht instanziert werden, sondern es wird "vererbt". Man nutzt aber "implements" statt "extends".

In der Dokumentation zum ArrayAccess-Interface sind vier Methoden beschrieben, die in unserem Beispiel in der Klasse Content implementiert werden müssen:

- offsetExists() wird aufgerufen, wenn man mit isset($content["tiltle"]) ermitteln möchte, ob ein Array-Eintrag existiert.
- offsetGet() wird aufgerufen, wenn man den Wert für $content["tiltle"] mit einem Getter bekommen möchte.
- offsetSet() wird aufgerufen, wenn man den Wert für $content["tiltle"] = "Mein Koch-Blog" mit einem Setter setzen möchte.
- offsetUnset() wird aufgerufen, wenn man mit unset einen Eintrag löschen möchte.

Hier ein Beispiel, wie die Implementierung der Methoden in einer eigenen Klasse Content erfolgen könnte.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    <?php

    class Content implements ArrayAccess
    {
      public string $title = "Mein Koch-Blog";

      public function offsetExists(mixed $offset): bool
      {
        if ($offset === "title") {
          echo 'offsetExists() wurde aufgerufen und der Eintrag existiert <br>';
          return true;
        }
        return false;
      }

      public function offsetGet(mixed $offset): mixed
      {
        if ($offset === "title") {
          echo 'offsetGet() wurde aufgerufen und der Eintrag mit return zurückgegeben <br>';
          return $this->title;
        }
        return null;
      }

      public function offsetSet(mixed $offset, mixed $value): void
      {
        if ($offset === "title") {
          echo 'offsetSet() wurde aufgerufen und der Eintrag in die Eigenschaft $title geschrieben <br>';
          $this->title = $value;
        }
      }

      public function offsetUnset(mixed $offset): void
      {
        if ($offset === "title") {
          echo 'offsetUnset() wurde aufgerufen und der Eintrag gelöscht <br>';
          $this->title = null;
        }
      }
    }

    // Hauptprogramm
    $content = new Content();

    isset($content["title"]);  // ruft offsetExists auf
    echo "Eintrag: " . $content["title"] . "<br>";  // ruft offsetGet auf

    $content["title"] = "Mein Hunde-Blog";  // ruft offsetSet auf
    echo "Eintrag: " . $content["title"] . "<br>";  // ruft offsetGet auf

    unset($content["title"]);  // ruft offsetUnset auf
    echo "Eintrag: " . $content["title"] . "<br>";  // ruft offsetGet auf

Ausgabe:
offsetExists() wurde aufgerufen und der Eintrag existiert
offsetGet() wurde aufgerufen und der Eintrag mit return zurückgegeben
Eintrag: Mein Koch-Blog
offsetSet() wurde aufgerufen und der Eintrag in die Eigenschaft $title geschrieben
offsetGet() wurde aufgerufen und der Eintrag mit return zurückgegeben
Eintrag: Mein Hunde-Blog
offsetUnset() wurde aufgerufen und der Eintrag gelöscht
offsetGet() wurde aufgerufen und der Eintrag mit return zurückgegeben
Eintrag:

Bitte versuchen Sie, die Ausgabe nachzuvollziehen. Es ist gar nicht so schwer.

Wichtig

Sie haben hier also zwei Dinge gelernt:

- Sie können ein (vorgegebenes) Interface implementieren.
- Sie wissen, dass man mit dem ArrayAccess-Interface auf ein Objekt zugreifen kann, als wäre es ein assoziatives Array.

Hier zum Download ein wirklich nutzbares ArrayAccess-Interface (ohne die didaktischen echo-Befehle) ContentModel.zip.