spl_autoload_register – SELFHTML-Forum Forum als Ergänzung zum SELFHTML-Wiki und zur Dokumentation SELFHTML https://forum.selfhtml.org/self spl_autoload_register Mon, 22 Feb 16 11:14:11 Z https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661475#m1661475 https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661475#m1661475 <p>Hallo werte Freunde,</p> <p>ich probiere mich gerade wieder mit Klassen und hab hier ein schönes Autoload gefunden. Gibt es einen Grund, warum</p> <pre><code class="block language-php"><span class="token function">spl_autoload_register</span><span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <p>include verwendet, statt bspw. include_once, oder gar require_once?</p> <p><a href="http://php.net/manual/de/function.spl-autoload-register.php#example-4337" rel="noopener noreferrer">http://php.net/manual/de/function.spl-autoload-register.php#example-4337</a></p> <p>Bis bald</p> spl_autoload_register Mon, 22 Feb 16 12:42:48 Z https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661485#m1661485 https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661485#m1661485 <p>Tach!</p> <blockquote> <p>ich probiere mich gerade wieder mit Klassen und hab hier ein schönes Autoload gefunden. Gibt es einen Grund, warum</p> <pre><code class="block language-php"><span class="token function">spl_autoload_register</span><span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <p>include verwendet, statt bspw. include_once, oder gar require_once?</p> </blockquote> <p>Nein, und diese Funktion lädt auch nichts nach. Sie registriert nur eine Nachladefunktion. Ob dann include oder include_once (oder die require-Pendants) verwendet werden, entscheidet diese Nachladefunktion. Und die kannst du dir ja so schreiben, wie du sie brauchst.</p> <p>dedlfix.</p> spl_autoload_register Mon, 22 Feb 16 20:05:58 Z https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661541#m1661541 https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661541#m1661541 <p>Moin!</p> <blockquote> <p>Hallo werte Freunde,</p> <p>ich probiere mich gerade wieder mit Klassen und hab hier ein schönes Autoload gefunden. Gibt es einen Grund, warum</p> <pre><code class="block language-php"><span class="token function">spl_autoload_register</span><span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <p>include verwendet, statt bspw. include_once, oder gar require_once?</p> <p><a href="http://php.net/manual/de/function.spl-autoload-register.php#example-4337" rel="noopener noreferrer">http://php.net/manual/de/function.spl-autoload-register.php#example-4337</a></p> </blockquote> <p>Der Beispielcode:</p> <pre><code class="block language-php"><span class="token function">spl_autoload_register</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$class</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">include</span> <span class="token string single-quoted-string">'classes/'</span> <span class="token operator">.</span> <span class="token variable">$class</span> <span class="token operator">.</span> <span class="token string single-quoted-string">'.class.php'</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre> <p>Ja, es gibt zwei Gründe.</p> <ol> <li>_once-Funktionen müssen intern Buch führen über die bereits geladenen Dateien. Das kostet Performance, weil vor allem relative Pfade erst einmal zu vollständigen, absoluten Pfaden im Dateisystem expandiert werden müssen. Du provozierst also eventuell Dateisystemzugriffe, auch wenn "once" letztendlich dann feststellen würde, dass die Datei bereits eingebunden war.<br> Weiterhin ist das PHP-Autoloading so gestrickt, dass die Autoload-Funktion, die ausschließlich den Code einer benötigten Klasse laden soll, eben nur genau dann aufgerufen wird, wenn diese Klasse, Interface oder Trait noch nicht bekannt ist. Kennt das laufende PHP-Skript hingegen die Klasse schon, wird die Autoload-Funktion nicht aufgerufen. Aus diesem Grund muss man nicht mittels _once verhindern, dass ein Skript, welches bereits eingebunden war und eine Klasse definiert, erneut eingebunden wird und die Klasse ein zweites Mal definiert - was mit einem Fehler enden würde.</li> <li>Der Grund, warum hier "include" und nicht "require" benutzt wird, liegt daran, dass PHP erlaubt, mehr als eine Autoload-Funktion zu registrieren. Sofern man beim Registrieren einer Funktion nichts anderes angibt, wird die hinzugefügte Funktion immer ans Ende der Liste aller registrierten Funktionen gehängt.<br> Wenn eine Klasse geladen werden soll, wird die erste Autoload-Funktion aufgerufen. Sie soll die Klasse laden. Gelingt das jedoch nicht, sollte die nächste Autoload-Funktion es versuchen. Das klappt aber nur, wenn die erste Funktion keinen Fehler erzeugt und das Skript abbricht. "require" bricht aber ab, wenn die gewünschte Datei nicht existiert - include lässt das Skript weiterlaufen.</li> </ol> <p>Du hast es hier also mit zwei relevanten Effekten zu tun: Erstens braucht es die Buchführung für bereits eingebundene Dateien nicht, und zweitens darf die Autoload-Funktion nicht abbrechen, wenn die Klasse nicht geladen werden kann.</p> <p>Autoloading ist übrigens schon uralt, Christian Seiler hat Ende 2007 dazu was ins Blog geschrieben: https://blog.selfhtml.org/2007/12/04/php-autoload/</p> <p>Die dort erwähnte Funktion "__autoload" sollte man unbedingt vermeiden - sie ist unhandlich und inkompatibel zu vielen Bibliotheken, die ihrerseits Autoloading machen.</p> <p>Außerdem sei dir an dieser Stelle wärmstens ans Herz gelegt, dich mal über <a href="https://getcomposer.org" rel="nofollow noopener noreferrer">"Composer"</a> zu informieren.</p> <p>Autoloading an sich ist eine relativ langweilige Sache, aber insbesondere nervig, wenn jeder Entwickler sein eigenes Dateinamensschema erfindet, und seinen eigenen Autoloader schreibt. Deshalb haben alle wichtigen PHP-Projekte sich zur <a href="http://www.php-fig.org/" rel="nofollow noopener noreferrer">PHP-FIG</a> zusammengeschlossen und einige Standards verabredet, an die sie sich halten wollen, um Code zueinander kompatibel zu machen. Für Autoloading sind die zwei Standards "PSR-0" und <a href="http://www.php-fig.org/psr/psr-4/" rel="nofollow noopener noreferrer">"PSR-4"</a> entstanden, und Composer erlaubt es auf sehr einfache Art, für eigenen Code das Autoloading zu definieren - was insbesondere vorteilhaft ist, wenn man noch fremde Bibliotheken mit einbindet.</p> <p>(Anmerkung: PSR-0 ist deprecated und nur noch relevant für Projekte, die keine Namespaces für ihre Klassen verwenden. Das ist typischerweise der Fall, wenn sie zu PHP 5.2 und älter kompatibel sein wollen/müssen, und bedeutet, dass uralte PHP-Versionen ohne Security-Fixes benutzt werden - bloß weg damit!)</p> <p>Grüße Sven</p> spl_autoload_register Mon, 22 Feb 16 16:37:56 Z https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661507#m1661507 https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661507#m1661507 <p>Hi dedlfix,</p> <blockquote> <p>Nein, und diese Funktion lädt auch nichts nach.</p> </blockquote> <p>Deswegen die Nachfrage. Ich hatte angenommen, das Klassen eventuell nachgeladen werden können.</p> <blockquote> <p>Und die kannst du dir ja so schreiben, wie du sie brauchst.</p> </blockquote> <p>Dann sollte ich doch besser</p> <pre><code class="block language-php"><span class="token keyword">require_once</span> </code></pre> <p>vorziehen, oder? Sagt mir zumindest mein Bauchgefühl. Wenn beim includen was schief geht, läuft das Script ja weiter. Also für mich eher ein unerwünschter Effekt.</p> <p>Bis bald</p> spl_autoload_register Mon, 22 Feb 16 18:25:12 Z https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661529#m1661529 https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661529#m1661529 <p>Tach!</p> <blockquote> <blockquote> <p>Nein, und diese Funktion lädt auch nichts nach.</p> </blockquote> <p>Deswegen die Nachfrage. Ich hatte angenommen, das Klassen eventuell nachgeladen werden können.</p> </blockquote> <p>Können ja auch, nur nicht mit der genannten Funktion. Die registriert nur eine Funktion, die PHP aufruft, wenn es eine ihm unbekannte Klasse vorfindet.</p> <blockquote> <p>Dann sollte ich doch besser</p> <pre><code class="block language-php"><span class="token keyword">require_once</span> </code></pre> <p>vorziehen, oder? Sagt mir zumindest mein Bauchgefühl. Wenn beim includen was schief geht, läuft das Script ja weiter. Also für mich eher ein unerwünschter Effekt.</p> </blockquote> <p>Wenn du das so haben möchtest, dann mach das so. Andererseits stirbt es ja sowieso, weil die Klasse nicht geladen werden konnte. Es sei denn, du hast noch andere Funktionen registriert, die die Klasse auf andere Weise besorgen.</p> <p>dedlfix.</p> spl_autoload_register Mon, 22 Feb 16 18:44:20 Z https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661534#m1661534 https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661534#m1661534 <p>Hi dedlfix,</p> <blockquote> <p>Können ja auch, nur nicht mit der genannten Funktion. Die registriert nur eine Funktion, die PHP aufruft, wenn es eine ihm unbekannte Klasse vorfindet.</p> </blockquote> <p>Ok, das hatte ich nicht ganz verstanden. Danke. Klassen sind Klasse :)</p> <blockquote> <p>Es sei denn, du hast noch andere Funktionen registriert, die die Klasse auf andere Weise besorgen.</p> </blockquote> <p>Nein, nur Autoload. Ich bleib wohl vorerst auch bei Autoload, ist ja super praktisch. Hätte ich das nur mal etwas früher gepeilt ...</p> <div class="signature">-- <br> Hosen sind Blau </div> spl_autoload_register Mon, 22 Feb 16 21:28:23 Z https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661550#m1661550 https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661550#m1661550 <p>Hi Sven,</p> <blockquote> <pre><code class="block language-php"><span class="token function">spl_autoload_register</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$class</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">include</span> <span class="token string single-quoted-string">'classes/'</span> <span class="token operator">.</span> <span class="token variable">$class</span> <span class="token operator">.</span> <span class="token string single-quoted-string">'.class.php'</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre> </blockquote> <p>Ich muss mich noch an die neue Forensoftware gewöhnen.</p> <blockquote> <ol> <li>_once-Funktionen müssen intern Buch führen über die bereits geladenen Dateien. Das kostet Performance, weil vor allem relative Pfade erst einmal zu vollständigen, absoluten Pfaden im Dateisystem expandiert werden müssen.</li> </ol> </blockquote> <p>Deine Performance-Tipps sind unbezahlbar. Von der internen Buchführung hatte ich keine Ahnung.</p> <blockquote> <ol start="2"> <li>"require" bricht aber ab, wenn die gewünschte Datei nicht existiert - include lässt das Skript weiterlaufen.</li> </ol> </blockquote> <p>Ich bleib doch beim includen :)</p> <blockquote> <p>Autoloading ist übrigens schon uralt, Christian Seiler hat Ende 2007 dazu was ins Blog geschrieben: https://blog.selfhtml.org/2007/12/04/php-autoload/</p> </blockquote> <p>Ja, ich weiss. Klassen sind ja noch viel älter, aber manchmal brauch ich etwas länger :) Ich hab gerade mal so ansatzweise den Sinn von Klassen verstanden. Das hoffe ich zumindest.</p> <blockquote> <p>Außerdem sei dir an dieser Stelle wärmstens ans Herz gelegt, dich mal über <a href="https://getcomposer.org" rel="nofollow noopener noreferrer">"Composer"</a> zu informieren.</p> </blockquote> <p>Konnte jetzt auf anhieb kein Projekt installieren. Das schaue ich mir morgen nochmal an.</p> <blockquote> <p>Für Autoloading sind die zwei Standards "PSR-0" und <a href="http://www.php-fig.org/psr/psr-4/" rel="nofollow noopener noreferrer">"PSR-4"</a> entstanden, und Composer erlaubt es auf sehr einfache Art, für eigenen Code das Autoloading zu definieren - was insbesondere vorteilhaft ist, wenn man noch fremde Bibliotheken mit einbindet. (Anmerkung: PSR-0 ist deprecated</p> </blockquote> <p>Passt wieder wunderbar, ich fang gerade an, mich in Klassen einzuarbeiten. Kann ich gleich halbwegs richtig starten.</p> <p>Vielen Dank für die ausführliche Erklärung! Immer wieder eine Freude, dich und Dedlfix zu lesen.</p> <p>Bis bald</p> <div class="signature">-- <br> Hosen sind Blau </div> spl_autoload_register Tue, 23 Feb 16 19:27:41 Z https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661658#m1661658 https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661658#m1661658 <p>Hi Sven,</p> <blockquote> <p>Außerdem sei dir an dieser Stelle wärmstens ans Herz gelegt, dich mal über <a href="https://getcomposer.org" rel="nofollow noopener noreferrer">"Composer"</a> zu informieren.</p> </blockquote> <p>Ich hab es jetzt installiert bekommen und ein Projekt erstellt. Jetzt habe ich hier die folgenden Verzeichnisse:</p> <pre><code class="block language-php"><span class="token operator">/</span>index<span class="token operator">.</span>php <span class="token operator">/</span>vendor<span class="token operator">/</span> <span class="token operator">/</span>vendor<span class="token operator">/</span>composer<span class="token operator">/</span> <span class="token operator">/</span>vendor<span class="token operator">/</span>monolog<span class="token operator">/</span> <span class="token operator">/</span>scr<span class="token operator">/</span><span class="token keyword">class</span><span class="token operator">/</span> <span class="token comment"># <-- hier hatte ich eigentlich vor, meine Klassen abzulegen</span> </code></pre> <p>Ich hatte irgendwo gesehen, dass ein Ordner „classes“ in Vendor war. Gehört er da rein? Ich hab den Nutzen für mich selbst noch nicht ganz erfassen können, sieht aber sehr Interessant aus.</p> <p>Bis bald</p> <div class="signature">-- <br> Hosen sind Blau </div> spl_autoload_register Tue, 23 Feb 16 20:26:07 Z https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661676#m1661676 https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661676#m1661676 <p>Moin!</p> <blockquote> <p>Hi Sven,</p> <blockquote> <p>Außerdem sei dir an dieser Stelle wärmstens ans Herz gelegt, dich mal über <a href="https://getcomposer.org" rel="nofollow noopener noreferrer">"Composer"</a> zu informieren.</p> </blockquote> <p>Ich hab es jetzt installiert bekommen und ein Projekt erstellt. Jetzt habe ich hier die folgenden Verzeichnisse:</p> <pre><code class="block language-php"><span class="token operator">/</span>index<span class="token operator">.</span>php <span class="token operator">/</span>vendor<span class="token operator">/</span> <span class="token operator">/</span>vendor<span class="token operator">/</span>composer<span class="token operator">/</span> <span class="token operator">/</span>vendor<span class="token operator">/</span>monolog<span class="token operator">/</span> <span class="token operator">/</span>scr<span class="token operator">/</span><span class="token keyword">class</span><span class="token operator">/</span> <span class="token comment"># <-- hier hatte ich eigentlich vor, meine Klassen abzulegen</span> </code></pre> </blockquote> <p>Bis hierhin schon prima. Wie man der Doku zu Composer entnehmen kann, musst du irgendwo, idealerweise am Anfang eines Skripts, die Datei <code>vendor/autoload.php</code> einbinden (ich würde es mit require machen - die wird gebraucht, sonst geht nix). Danach kannst du alle Klassen der eingebundenen Pakete sowie ggf. auch deren Funktionen direkt benutzen.</p> <p>Dein eigener Code darf in jedem anderen Verzeichnis liegen, dass du magst. "src" bietet sich irgendwie an. Die Lage deiner "index.php" ist allerdings suboptimal, weil sie nahelegt, dass das die allgemeine Einstiegsdatei für die Website ist - und wenn das so ist, kann man allen Code und alle Konfigurationsdateien (mit Passworten?) dieser Website direkt mit dem Browser aufrufen, wenn man den Dateinamen kennt (oder ihn aus Fehlermeldungen gesagt bekommt, oder suchen darf).</p> <p>Deshalb: "public/index.php" draus machen - das Verzeichnis "public" (es darf auch anders heißen) ist dein DOCUMENT_ROOT - muss im HTTP-Server auch so konfiguriert werden. Dann ändert sich logischerweise der Pfad für das Autoloading: <code>require "../vendor/autoload.php"</code>.</p> <p>Composer bietet dir auch an, das Autoloading für deinen eigenen Code mit zu übernehmen. Ich empfehle dir, für Klassen unbedingt PSR-4 zu verwenden. Zum einen benutzen es alle anderen Pakete ebenfalls, und es kommt ein Gefühl der einheitlichen Codeorganisation auf. Zum anderen funktioniert PSR-4 automatisch sofort, wenn man eine neue Klasse in einer neuen Datei hinzufügt. Nur wenn du keine Namespaces benutzt, musst du PSR-0 nehmen (und bis vermutlich zu längeren Pfaden für die Klassen gezwungen).</p> <blockquote> <p>Ich hatte irgendwo gesehen, dass ein Ordner „classes“ in Vendor war. Gehört er da rein? Ich hab den Nutzen für mich selbst noch nicht ganz erfassen können, sieht aber sehr Interessant aus.</p> </blockquote> <p>Es gibt Dateien unter "vendor/composer", die sich mit den Details des Autoloadings befassen. Die kannst du interessehalber anschauen, aber sie werden automatisch generiert und sind deshalb nicht zu bearbeiten.</p> <p>Darüber hinaus kann jedes beliebige Paket seine Verzeichnisstruktur frei wählen, also auch "classes" nennen. Der wichtigste Vorteil von Composer ist ja, dass man durch Autoloading, das von jedem Paket definiert wird, nicht mehr wissen muss, wo genau sich eine DATEI befindet. Man muss nur wissen, welche KLASSE man benutzen will. Genau so, wie URLs von Dateien auf dem Webserver unabhängig werden, werden verwendete Klassen von ihren Dateien unabhängig.</p> <p>Grüße Sven</p> spl_autoload_register Tue, 23 Feb 16 21:23:12 Z https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661702#m1661702 https://forum.selfhtml.org/self/2016/feb/22/spl-autoload-register/1661702#m1661702 <p>Hi Sven,</p> <blockquote> <p>Danach kannst du alle Klassen der eingebundenen Pakete sowie ggf. auch deren Funktionen direkt benutzen.</p> </blockquote> <p>Jetzt habe ich auch endlich den Sinn von Frameworks verstanden :) Ich werde Klassenprogrammierer :)</p> <blockquote> <p>Dein eigener Code darf in jedem anderen Verzeichnis liegen, dass du magst. "src" bietet sich irgendwie an. Die Lage deiner "index.php" ist allerdings suboptimal</p> </blockquote> <p>Ich wollte es nur etwas Übersichtlich halten, die Projekte liegen immer in einem Unterordner im entsprechenden Document-Root. Ich habe also immer die möglichkeit, wichtiges ausserhalb der Doc-Root abzulegen. Das hatten wir glücklicherweise vor Jahren schon mehrfach hier durchgekaut, vorallem mit dedlfix.</p> <blockquote> <p>Nur wenn du keine Namespaces benutzt, musst du PSR-0 nehmen (und bis vermutlich zu längeren Pfaden für die Klassen gezwungen).</p> </blockquote> <p>Mit Namespaces muss ich erstmal rumspielen, ansich sieht es ja einfach aus.</p> <blockquote> <p>Man muss nur wissen, welche KLASSE man benutzen will. Genau so, wie URLs von Dateien auf dem Webserver unabhängig werden, werden verwendete Klassen von ihren Dateien unabhängig.</p> </blockquote> <p>Ich freu mich schon auf Symfony, und das ein oder andere Framework :)</p> <p>Danke für die Hilfe! Ich werde sicher eine Weile brauchen, bis ich es tatsächlich verinnerlicht habe, aber der Anfang ist endlich getan.</p> <p>Bis bald</p> <div class="signature">-- <br> Hosen sind Blau </div>