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
- Finden
- Löschen
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_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
| 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
| 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.