Kategorie PHP

Klassen in PHP nachladen mit SPL_autoload

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:



<span class="token function">spl_autoload_register</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token variable">$auto</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">auto</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

PHP

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:


<span class="token variable">$actdir</span> <span class="token operator">=</span> <span class="token function">dirname</span><span class="token punctuation">(</span><span class="token constant">__FILE__</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// aktuelles Verzeichnis bestimmen</span>
<span class="token function">set_include_path</span><span class="token punctuation">(</span><span class="token function">implode</span><span class="token punctuation">(</span><span class="token constant">PATH_SEPARATOR</span><span class="token punctuation">,</span> <span class="token keyword">array</span><span class="token punctuation">(</span><span class="token variable">$actdir</span> <span class="token punctuation">.</span> <span class="token operator">/</span>classes<span class="token operator">/</span><span class="token string">", get_include_path())); // das Unterverzeichnis "</span>classes" in den Suchpfad aufnehmen
<span class="token function">spl_autoload_register</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// nun wird nach Klassen auch in dem Verzeichnis "classes" gesucht</span>
<span class="token variable">$auto</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">auto</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// die Klasse "auto" kann nun auch im Unterverzeichnis "classes" liegen und wird gefunden</span>
PHP

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


<span class="token keyword">echo</span> <span class="token function">spl_autoload_extensions</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
PHP

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:


<span class="token function">spl_autoload_extensions</span><span class="token punctuation">(</span><span class="token string">'.php,.inc'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
PHP

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:


<span class="token function">spl_autoload_register</span><span class="token punctuation">(</span><span class="token string">'meinAutoload'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">meinAutoload</span><span class="token punctuation">(</span><span class="token variable">$className</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token variable">$filename</span> <span class="token operator">=</span> <span class="token function">str_replace</span><span class="token punctuation">(</span><span class="token string">'_'</span><span class="token punctuation">,</span> <span class="token string">'/'</span><span class="token punctuation">,</span> <span class="token variable">$className</span><span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token string">'.php'</span><span class="token punctuation">;</span>
  <span class="token keyword">include</span> <span class="token variable">$filename</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token variable">$uhrzeit</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">AS_uhrzeit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
PHP

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

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.