Facebook
Twitter
Google+
Kommentare
10

include vs. include_once

Nur schon mal vorweg, alles was ich hier schreibe gilt auch für require und require_once.

Ich wurde schön des öfteren gefragt, wann man include und wann include_once verwenden sollte. Die Antwort ist meiner Meinung nach ganz einfach. Include nie, include_once immer. Aber wie meistens kann man sich über dieses Thema auch gediegen streiten. Ich, in meiner objektorientierten Denkweise, sehe aber keinen Grund eine Datei mehrmals inkludieren zu wollen.

Pro Datei existiert genau eine Klasse und kein ausführbarer Code. Die einzige Stelle, in der solcher Code vorhanden ist, sollte die index.php sein. Natürlich gibt es auch ein paar Ausnahmen, die von PHP vorgegeben sind. So würde ich die autoload Methoden zum Beispiel nicht in eine Klasse packen. Aber auch eine Datei, in der diese Methoden vorhanden sind, sollte genau einmal inkludiert werden. In den meisten Fällen kann ein include durch die Verwendung einer Funktion ersetzt werden. Wer includes einsetzt, um duplizierten Code zu verhindern, der sollte auf traits warten, denn diese sind für genau solche Fälle gemacht. Und wenn ich ehrlich bin, dann habe ich lieber doppelten Code, als includes, denn hier versagen wenigstens die Methoden der statischen Codeanalyse nicht. Und auch wenn sie vielleicht nicht versagen, erschwert wird es dadurch erheblich.

Falls ihr euch nichts unter dem Codeduplizieren vorstellen könnt, hier ein kleines Beispiel:

<?php

  class ASingleton
  {
     // ...
     public static function getInstance( )
     {
       return include 'singleton_getInstance.php';
     }
  }

?>

In der singleton_getInstance.php steht nun der Code, der dazu benötigt wird eine Instanz zu erstellen. Eine Klasse BSingleton könnte nun genau den gleichen Code Snippet verwenden. Vielleicht denkt ihr euch jetzt, dass man das ganze auch über Ableitung hinbekommen könnte, aber da gibt es ein Problem. Zieht man hier Vererbung hinzu, so verbauen wir uns die Möglichkeit von anderen Klassen abzuleiten und in den meisten Fällen wollen wir das nicht.

Über den Autor

Nils Langner

Nils Langner ist der Gründer von "the web hates me" und auch der Hauptautor. Im wahren Leben leitet er das Qualitätsmanagementteam im Gruner+Jahr-Digitalbereich und ist somit für Seiten wie stern.de, eltern.de und gala.de aus Qualitätssicht verantwortlich. Nils schreibt seit den Anfängen von phphatesme, welches er ebenfalls gegründet hat, nicht nur für diverse Blogs, sondern auch für Fachmagazine, wie das PHP Magazin, die t3n, die c't oder die iX. Nebenbei ist er noch ein gern gesehener Sprecher auf Konferenzen. Herr Langner schreibt die Texte über sich gerne in der dritten Form.
Kommentare

10 Comments

  1. Hallo,

    ich verwende immer require_once() obwohl ich mal irgendwo gelesen hab das es angeblich ein Performance-Killer sein soll.
    Hat jemand dazu nähere Informationen?

    Reply
  2. require_once ist kein Performancekiller. Bei require wird das Script halt angehalten wenn die Datei nicht da ist, bei include wird nur eine Fehlermeldung geworfen und das Script weiter ausgeführt 🙂

    Der Phpperformanceblog hat das schon mal verglichen, ausführtechnisch liegen die gleichauf. Glaub ich mich zu erinnern.

    Reply
  3. Ich verwende eigentlich nur include statments. Dazu packe ich einfache define Anweisungen um die entsprechende Klasse.

    Beispiel:

    class.php

    index.php

    gruss axel

    Reply
  4. hmmm irgendwie wird mein code wegoptimiert 😀

    zweiter versuch:

    Beispiel:

    class.php

    index.php

    include( ‚class.php‘ );
    include( ‚class.php‘ );
    include( ‚class.php‘ );
    include( ‚class.php‘ );

    gruss axel

    Reply
  5. versuch 3:

    class.php

    if( defined( __FILE__ ) )
    {
    return;
    }

    define( __FILE__, 1 );

    class Asa
    {
    public function cool()
    {
    die(‚happy x-mas‘);
    }
    }

    index.php

    include( ‚class.php‘ );
    include( ‚class.php‘ );
    include( ‚class.php‘ );
    include( ‚class.php‘ );

    Reply
  6. Ich denke es gibt einige Strategien um das Includen von Dateien zu beschleunigen. Abhängig vom Projekt bzw. dessen Laufzeitumgebung lässt sich in die eine oder andere Richtung hinoptimieren. Ich verwende i.d.R. eine Kombination von autoload und include, sprich in einer mittels autoload registrierten Funktion wird der include durchgeführt. Persönlich habe ich den Eindruck dass dies deutlich performanter ist als include_once oder require_once. In neueren PHP Versionen sollen die beiden _once Funktionen zwar einen „realpath cache“ zur Performance-Steigerung bekommen haben, das konnte ich aber lokal in verschiedenen Tests nicht direkt nachvollziehen. Ein weiterer wichtiger Punkt ist wie ich finde die Verwendung von absoluten Includepfaden (bzw. realativ zu einem absoluten Verzeichnis). Dies steigert die Performance ebenfalls da nur ein File-Request auf OS Basis abgesetzt wird (direct hit), im Gegensatz zu x Leseanfragen, für (fast) alle Verzeichnisse die als include_path gesetzt wurden. Alternativ dazu sind Opcode Caches auch ein Ansatz um viele Dateizugriffe zu verhindern.

    Reply
  7. Duplicate Code ist ein Anti-Pattern und sollte nie vorkommen. Das wie von dir oben beschrieben zu verhindern ist eher Banane. Ich sehe keinen Vorteil darin, den Methodenkörper auszulagern. Mehr als eine Klasse erweitern kann und soll PHP nicht. Dafür gibt es interfaces. Das ist ohnehin auch nicht nötig, wenn man eine sinnvolle Klassenvererbung wählt.

    Aber vielleicht verstehe ich dich auch falsch.

    Reply
  8. @unset: naja versuche mal ein Singleton schön über Vererbung zu implementieren, ohne dir dabei was für die Zukunft zu verbauen. In den meisten Fällen wirst du dann doch duplizierten Code haben.

    Reply
  9. *_once ist teuer! Genau aus dem Grund gibt es in APC die Option die beiden Funktion durch eine optimierte Version überschreiben zu lassen.

    Wichtig ist auch, dass *immer* absolute Pfade verwendet werden und das der include_path möglichst klein ist.

    Setzt einfach mal in APC die Option apc.stat=0. Daraufhin überprüft APC nicht mehr bei jedem Requests ob sich die PHP-Datei verändert hat. Zusätzlich, und das ist das schöne, gibt APC dann eine Fehlermeldung aus, wenn die Datei nicht gecached werden kann, z.B. wegen relativen Pfaden.

    Reply

Leave a Comment.

Link erfolgreich vorgeschlagen.

Vielen Dank, dass du einen Link vorgeschlagen hast. Wir werden ihn sobald wie möglich prüfen. Schließen