Kategorie PHP

Klassen in PHP nachladen mit SPL_autoload

Lesezeit ca. 4 Min.

Eine häufig vorkommende Aufgabe in der Programmierung von PHP Projekten ist das Nachladen von Klassen. Bei kleineren Projekten, in denen man lediglich einige Funktionalitäten in einer externen PHP Datei auslagert, ist die gängige Vorgehensweise die Verwendung von include oder require.
Zur Verwendung dieser Befehle habe ich einen gesonderten Artikel geschrieben: Include versus Require. Doch je größer das Projekt wird und je mehr Komponenten bzw. Klassen man in gesonderten Dateien für das Projekt auslagert, desto unhandlicher wird diese Vorgehensweise. Aus diesem Grund benötigt man ein Verfahren, welches die benötigten ausgelagerten Sourcen automatisch nachlädt. Zu diesem Zweck liefert die Standard PHP Library (SPL) eine Komponente namens spl_autoload.

Details zu dieser und den weiteren enthaltenen Funktionen findet man in der PHP Dokumentation. Um Klassen in PHP mit SPL_autoload nachladen zu können, die sich in demselben Verzeichnis befinden, wie das ausführende Skript, wird die Funktion spl_autoload_register() aufgerufen.

Um die Sache nicht zu theoretisch werden zu lassen, sehen wir uns dazu gleich ein Beispiel an. Wir haben unser Hauptskript index.php und wollen darin die Klasse auto verwenden. Diese ist in der Datei auto.php definiert. Wir könnten nun entweder die Datei auto.php durch include oder require laden oder wir schreiben folgendes in unsere index.php:

spl_autoload_register();
$auto = new auto();

Die Klasse auto wird nun automatisch geladen und kann im Skript verwendet werden. Die Klasse bzw. das PHP-Skript, welches denselben Namen wie die Klasse trägt, wird nicht nur im aktuellen Pfad gesucht, sondern auch in allen anderen Pfaden, die sich im Include-Pfad befinden. Soll daher die Klasse in einem Unterverzeichnis abgelegt werden, welches sich nicht im Include-Pfad befindet, so muss dieser Pfad lediglich in den Include-Pfad aufgenommen werden. Im folgenden Beispiel wird gezeigt, wie dies geschieht:

// aktuelles Verzeichnis bestimmen 
$actdir = dirname(__FILE__);
// das Unterverzeichnis "classes" in den Suchpfad aufnehmen
set_include_path(implode(PATH_SEPARATOR,array($actdir."/classes/",get_include_path())));
// nun wird nach Klassen auch in dem Verzeichnis "classes" gesucht
spl_autoload_register();
// die Klasse "auto" kann nun auch im Unterverzeichnis 
// "classes" liegen und wird gefunden
$auto = new auto(); 

Mit der Funktion spl_autoload_extensions() kann man sehen, nach welchen Dateinamenserweiterungen spl_autoload sucht und in welcher Reihenfolge. Ein

echo spl_autoload_extensions();

zeigt eine Liste mit den Dateinamenserweiterungen an. Standardmäßig wird nach “inc” und “php” gesucht. Diese Reihenfolge kann geändert werden und es können weitere Dateinamenserweiterungen hinzugefügt werden. Im folgenden Beispiel wird die Reihenfolge umgedreht:

spl_autoload_extensions('.php,.inc');

Jetzt wird zuerst nach der Dateinamenserweiterung “php” und erst danach nach “inc” gesucht.

Doch das ist noch nicht alles, was man mit spl_autoload anstellen kann. Manchmal hat man es mit externen Libraries zu tun und diese haben eine eigene Struktur, ihre Klassen abzulegen. Nehmen wir das Beispiel, dass meine Klasse in dem Unterverzeichnis “AS” liegt und darin befindet sich eine Datei uhrzeit.php. In dieser Datei habe ich nun eine Klasse namens “AS_uhrzeit”. Um diese Klasse in meinem Ausgangsskript zu finden, muss ich spl_autoload ein wenig aufbohren, was aber auch recht einfach bewerkstelligt werden kann.

Ich kann der Funktion spl_autoload_register() als Parameter den Namen einer Funktion übergeben, nennen wir sie “meinAutoload”. Innerhalb dieser Funktion kann ich ein Suchmuster definieren, wonach spl_autoload nach Klassen suchen soll. Für das vorgenannte Beispiel sieht das so aus:

spl_autoload_register('meinAutoload');

function meinAutoload($className) {
  $filename = str_replace('_', '/', $className) . '.php';
  include $filename;
}

$uhrzeit = new AS_uhrzeit();

Hiermit wird nun im Verzeichnis “AS” nach der Klasse “AS_uhrzeit” gesucht und diese für die weitere Verwendung geladen.

Selbstverständlich muss man keine eigene Funktion definieren, sondern man kann auch eine anonyme Funktion verwenden.

spl_autoload_register(function($classname){
  $filename = str_replace('_', '/', $classname) . '.php';
  include $filename;
});

Eine weitere Besonderheit ist der Autoload-Stack. Wenn ich also verschiedene Libraries habe mit unterschiedlichen Notationen für die Namensgebung der Klassen, so kann ich mehrere Funktionen schreiben, wie oben gezeigt, und sie alle mit spl_autoload_register([Funktionsname]) in einen Stack laden. Dann werden all diese Funktionen durchlaufen, um nach einer bestimmten Klasse zu suchen. Den Stack kann ich mir mit der Funktion spl_autoload_functions() anzeigen lassen. Brauche ich eine bestimmte Klasse nur an einer Stelle meines Programmes, so kann ich zum Laden den Autoload-Stack befüllen und nach Ausführung einer oder mehrerer Methoden der Klasse mit der Funktion spl_autoload_unregister([Funktionsname]) die entsprechende Suchroutine wieder vom Stack löschen und damit den Speicher für die weitere Ausführung entlasten.

Somit lassen sich insbesondere in größeren Anwendungen eine Reihe von Suchmuster erstellen, die Klassen in PHP mit SPL_autoload nachladen helfen.

Ähnliche Artikel:

Fragen oder Feedback zu diesem Artikel

Deine E-Mail-Adresse wird nicht veröffentlicht.