PHP Autoloader Klassenindex

Der PHP-Autoloader legt den Ort einer gefundenen Klassendefinition in einem Index ab. Dadurch wird ein erneutes Suchen im Dateisystem unnötig.

Der Index muss folgende Aufgaben erfüllen:

Speichern findet nur dann statt, wenn eine Klasse noch nicht im Index existiert. Der Autoloader sucht die Klasse im Dateisystem und speichert danach den Ort im Index ab.

Löschen findet nur dann statt wenn sich der Ort einer Klassendefinition geändert hat. Der Autoloader holt sich vom Index den vermeintlichen Ort einer Klassendefintion ab, findet dort aber keine passende Klassendefinition. Darauf hin löscht der Autoloader diesen Ort im Index. Der neue Ort wird im Dateisystem gesucht und gespeichert.

Die beiden Anwendungsfälle Speichern und Löschen finden unverhältnismäßig selten statt, so dass sie keine weitere Betrachtung für die Indexwahl Wert sind. Das Lesen ist der häufigste Anwendungsfall der für die Wahl einer der folgenden Indizes entscheidend ist:

AutoloaderIndex_File
Eine Hash-Tabelle liegt in eine der folgenden Formen gespeichert in einer Datei:
AutoloaderIndex_SerializedHashtable
Die Hashtabelle wird serialisiert.
AutoloaderIndex_SerializedHashtable_GZ
Die Hashtabelle wird wie in AutoloaderIndex_SerializedHashtable serialisiert und zusätzlich mit gzip gepackt. Das Packen soll die Plattennutzung auf ein Minimum reduzieren.
AutoloaderIndex_IniFile
Die Hashtabelle wird in einer Konfigurationsdatei hinterlegt.
AutoloaderIndex_CSV
Die Hashtabelle wird in einer CSV-Datei hinterlegt.
AutoloaderIndex_PHPArrayCode
Die Hashtabelle wird direkt als PHP-Code in einer Datei hinterlegt. Diese Implementierung ist für Testzwecke gedacht. Sie sollte wegen der potentiellen Gefahr Fremdcode auszuführen nicht produktiv zum Einsatz kommen.
AutoloaderIndex_IniFile, AutoloaderIndex_CSV und AutoloaderIndex_PHPArrayCode sind vom Menschen lesbar und können bei Bedarf händisch geändert werden. Sollte dies nicht erforderlich sein ist eine AutoloaderIndex_SerializedHashtable-Implementierung wegen des geringeren Initialisierungsaufwand zu bevorzugen.
AutoloaderIndex_PDO
Ein Index, der mittels Standard-SQL ein beliebiges PDO Objekt anspricht.

Mit der Objektmethode Autoloader::setIndex(AutoloaderIndex $index) kann man den Index im Autoloader setzen:

<?php

require dirname(__FILE__) . '/autoloader/Autoloader.php';

// Wahl einer AutoloaderIndex-Implementierung
$index = new AutoloaderIndex_IniFile();

/* Holt den automatisch registrierten Autoloader für den
 * Klassenpfad dieser Datei.
 */
$autoloader Autoloader::getRegisteredAutoloader();

// Der Autoloader verwendet nun $index als Index
$autoloader->setIndex($index);

Wenn man dies nicht macht, wird ein AutoloaderIndex_SerializedHashtable_GZ-Index verwendet.

AutoloaderIndex_File

Komplexität
Aktion Komplexität
Initialisierung O(n)
Anfrage O(1)

Beim AutoloaderIndex_File ist der Initialisierungsaufwand und Speicherbedarf entscheidend. Zum Initialisieren muss die komplette Datei gelesen werden und danach als Hash-Tabelle im Speicher gehalten werden. Dies ist selbstverständlich linear abhängig von der Indexgröße. Für die Komplexität spielt die konkrete AutoloaderIndex_File-Implementierung keine Rolle.

Anfragen an den Index laufen dafür unabhängig von der Indexgröße konstant schnell ab. D.h. dieser Index ist vorzuziehen, wenn ein großer Teil des Indexes tatsächlich angefragt wird.

AutoloaderIndex_PDO

Komplexität
Aktion Komplexität
Initialisierung O(1)
Anfrage O(log(n))

Über AutoloaderIndex_PDO kann man schwer eine pauschale Aussage machen, da die Eigenschaften stark von der PDO-Implementierung abhängen. Z.B. könnte man sich eine PDO-Implementierung vorstellen, der eine serialisierte Hash-Tabelle zu Grunde liegt und damit identische Eigenschaften wie AutoloaderIndex_SerializedHashtable hat.

Es ist aber stark anzunehmen, dass man meistens ein DBS mit einem für das Dateisystem geeigneten Index (z.B. ein B-Baum) verwendet. Im Webumfeld wird man häufig SQLite, MySQL, PostgreSQL oder MSSQLServer antreffen (Liste mit PDO-Implementierungen).

Ein solcher Index hat die Eigenschaft, keinen Initialisierungsaufwand zu betreiben. Allerdings ist die Komplexität einer Anfrage von der Indexgröße abhängig. Diese ist i.d.R. logarithmisch.

Diese Implementierung ist insbesondere bei einem sehr großen Index mit einer genügend kleinen Nutzung zu bevorzugen.