Kai: include_once vs. include

Ich verstehe nicht ganz,
wann setze ich include_once wann include?

Kai

  1. Hi Kai,

    Ich verstehe nicht ganz,
    wann setze ich include_once wann include?

    probier doch mal folgendes:

      
    <?php  
    include_once("home/user/datei.php");  
    include_once("home/user/datei.php");  
    ?>  
    
    

    und das gleich nochmal mit include (wobei der Pfad zu deiner zu inkludierenden Datei natürlich stimmen muss)

  2. Ich verstehe nicht ganz,
    wann setze ich include_once wann include?

    Du bist ein Theoretiker. Wenn Du ein Praktiker wärst, hättest Du den Unterschied längst selbst bemerkt.

    Horst

  3. Hi,

    Ich verstehe nicht ganz,
    wann setze ich include_once wann include?

    das suggerieren doch schon die Namen. ;-)

    Bei kleinen, überschaubaren Scripts is include völlig okay.
    Wenn aber in einem größeren Projekt die Möglichkeit besteht, dass eine Scriptdatei von mehreren anderen Modulen eingebunden wird, gibt es Probleme, weil dann z.B. Funktionen mehrmals definiert werden (wenn auch identisch). In solchen Fällen sorgt include_once anstatt include dafür, dass der Code tatsächlich nur einmal eingebunden wird, auch wenn mehrere include_once-Anweisungen darauf verweisen.

    Ciao,
     Martin

    --
    Der Afrika-Forscher wird gefragt: "Stimmt es, dass man nicht von Löwen angefallen wird, wenn man eine Fackel trägt?" - "Kommt drauf an. Man muss die Fackel sehr schnell tragen."
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    1. [latex]Mae  govannen![/latex]

      Bei kleinen, überschaubaren Scripts is include völlig okay.
      Wenn aber in einem größeren Projekt die Möglichkeit besteht, dass eine Scriptdatei von mehreren anderen Modulen eingebunden wird, gibt es Probleme, weil dann z.B. Funktionen mehrmals definiert werden (wenn auch identisch). In solchen Fällen sorgt include_once anstatt include dafür, dass der Code tatsächlich nur einmal eingebunden wird, auch wenn mehrere include_once-Anweisungen darauf verweisen.

      Diese Probleme würden auch schon bei kleinen, überschaubaren Projekten auftreten wenn ein Code mehrfach eingebunden werden kann, insofern verstehe ich absolut nicht, inwiefern du das an der Größe des Projektes festmachen willst.

      Es kommt vielmehr darauf an, was konkret im Include steht. Klassen, Funktionen und Konstanten beispielsweise sind ein sicheres Zeichen, daß include nicht passt.

      Stur lächeln und winken, Männer!
      Kai

      --
      var jQuery = $(hit);
      Unsere Identität entnehmen Sie bitte dem beigefügten Auszug aus den Personenstandsbüchern. Gegen die Assimilierung in unser Kollektiv ist nach dem ABGB (§666, Abs. 3/IV) kein Rechtsmittel zulässig. Wir bitten um Ihr Verständnis.
      SelfHTML-Forum-Stylesheet
      1. Hallo,

        Wenn aber in einem größeren Projekt die Möglichkeit besteht, dass eine Scriptdatei von mehreren anderen Modulen eingebunden wird, gibt es Probleme, weil dann z.B. Funktionen mehrmals definiert werden (wenn auch identisch). In solchen Fällen sorgt include_once anstatt include dafür, dass der Code tatsächlich nur einmal eingebunden wird, auch wenn mehrere include_once-Anweisungen darauf verweisen.
        Diese Probleme würden auch schon bei kleinen, überschaubaren Projekten auftreten wenn ein Code mehrfach eingebunden werden kann, insofern verstehe ich absolut nicht, inwiefern du das an der Größe des Projektes festmachen willst.

        weil "kleine, überschaubare Projekte" selten mehr als eine include-Verschachtelungstiefe haben und die includes in der Regel an prominenter Stelle am Anfang der Hauptdatei stehen. Ist das nicht der Fall, würde ich das Projekt ungeachtet seiner Größe auch nicht mehr "überschaubar", oder besser übersichtlich nennen.

        Es kommt vielmehr darauf an, was konkret im Include steht. Klassen, Funktionen und Konstanten beispielsweise sind ein sicheres Zeichen, daß include nicht passt.

        Wenn das Projekt so sauber strukturiert ist, dass das nur an einer Stelle geschieht, ist alles in Ordnung.

        Ciao,
         Martin

        --
        Auch in Eckkneipen geht es manchmal rund.
        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
        1. hi,

          Wenn das Projekt so sauber strukturiert ist, dass das nur an einer Stelle geschieht, ist alles in Ordnung.

          Sehe ich auch so und gehe sogar noch einen Schritt weiter: Bei einem sauber strukturierten Projekt ist eine Zeile wie include_once oder require_once nicht notwendig. D.h., dass eine etwaige Warnung auf redeklarierte Sourcen den Entwickler darauf hinweisen sollte, nicht etwa include_once zu notieren, sondern seine Strukturen zu überdenken.

          Das ist bei vielen Krankheiten auch so: Es nützt meistens nichts, an den Symptomen herumzudoktieren.
          Es ist jedoch irgendwann einmal wichtig, den Unterschied zwischen include und require zu kennen ;)

          Horst Schweißfuß

          --
          Stopfpilze sind unbekömmlich.
          1. Hi,

            mal so rein aus Interesse:

            Sehe ich auch so und gehe sogar noch einen Schritt weiter: Bei einem sauber strukturierten Projekt ist eine Zeile wie include_once oder require_once nicht notwendig.

            Angenommen du möchtest in einem Script 2 Datenbank-Tabellen abfragen. Ich gehe mal davon aus, dass dafür je eine Mapper-Klasse erstellt wird, die wiederum auf einer Klasse basiert, welche die Grundfunktionalität bereitstellt.

            Da beide Mapper-Klassen die Basisklasse erben, hätte man ja nun schon einen Konflikt. Wie wäre da dein Lösungsansatz?

            1. Moin!

              Sehe ich auch so und gehe sogar noch einen Schritt weiter: Bei einem sauber strukturierten Projekt ist eine Zeile wie include_once oder require_once nicht notwendig.

              Angenommen du möchtest in einem Script 2 Datenbank-Tabellen abfragen. Ich gehe mal davon aus, dass dafür je eine Mapper-Klasse erstellt wird, die wiederum auf einer Klasse basiert, welche die Grundfunktionalität bereitstellt.

              Da beide Mapper-Klassen die Basisklasse erben, hätte man ja nun schon einen Konflikt. Wie wäre da dein Lösungsansatz?

              Siehe https://forum.selfhtml.org/?t=213000&m=1455865, letzter Absatz.

              - Sven Rautenberg

              1. Hi,

                Da beide Mapper-Klassen die Basisklasse erben, hätte man ja nun schon einen Konflikt. Wie wäre da dein Lösungsansatz?

                Siehe https://forum.selfhtml.org/?t=213000&m=1455865, letzter Absatz.

                Klar, Autoloading ist eine Alternative. Falls er darauf abzielen wollte, kann ich dem zustimmen.

                Sein Beitrag liest sich aber so, als ob man bei einem "sauber strukturierten Projekt" alle benötigten Ressourcen problemlos mit einfachen require-Anweisungen laden könnte ohne Konflikte zu bekommen.

      2. Es kommt vielmehr darauf an, was konkret im Include steht. Klassen, Funktionen und Konstanten beispielsweise sind ein sicheres Zeichen, daß include nicht passt.

        Wolltest Du damit sagen:

        "sind ein sicheres Zeichen, dass require_once in den allermeisten meisten Fällen sehr viel besser passt"?

        Dann "sag" es doch - und auch was warum besser passt:

        require  : wird benötigt
        _once    : Das Redeklarieren von Klassen, Funktionen und Konstanten würde einen Fehler "schmeißen".

        Jörg Reinholz

  4. Moin!

    Ich verstehe nicht ganz,
    wann setze ich include_once wann include?

    Du vermeidest beides am Besten.

    Warum? Weil beides im Fehlerfall nur eine Warnung produziert und ansonsten weitermacht. Der Fehlerfall bedeutet aber, dass Dinge, die du anscheinend als wichtig erachtet hast (sonst wären sie nicht eingebunden worden), nicht geladen werden konnten. Das wird man in der Regel nicht einfach ignorieren wollen.

    Nutze deshalb require und require_once. Diese beiden Varianten brechen das Skript ab, wenn die einzubindende Datei nicht eingebunden werden kann.

    Jetzt bleibt nur noch die Frage "mit _once oder ohne". Auch hier ist die Antwort eindeutig: Wenn's geht, lieber ohne. Denn das Verwalten aller bisher eingebundenen Dateien kostet Speicher und Rechenzeit. Die ultimative Performance kriegt man nur ohne "_once". Andererseits gibt es Code, der an mehr als einer Stelle dieselbe Datei einbinden will, und in dieser Datei stehen Definitionen, die man nur einmal pro Skriptablauf machen darf. Dann wäre mit "_once" besser.

    Dies gilt übrigens ausdrücklich für das Laden von Klassen via Autoloader NICHT! Denn die Autoload-Funktion wird nur aktiviert, wenn die Klasse noch nicht bekannt ist - das ist aber NACH dem Einbinden der Klassendatei nie mehr der Fall, also wird der Autoloader kein zweites Mal versuchen, diese Klasse einzubinden. Folglich ist "require_once()" an dieser Stelle überflüssig.

    - Sven Rautenberg

    1. Schönen guten Tag Sven,

      Weil beides im Fehlerfall nur eine Warnung produziert und ansonsten weitermacht.

      was genau meinst Du denn mit "Fehlerfall"? Dass die Ressource, die includet werden soll, nicht vorhanden ist? Oder dass aus einem technischen Grund der Include nicht funktioniert hat? Falls letzteres überhaupt möglich ist, dann würde doch die komplette Skriptverarbeitung auch nicht funktionieren. Oder meintest Du mit "Fehlerfall" etwas ganz anderes?

      Mit lieben Grüßen

      H. Wolowitz

      --

      Gut, dann können wir die Zettel von den Laternen nehmen...
      1. Tach!

        Weil beides [include/include_once] im Fehlerfall nur eine Warnung produziert und ansonsten weitermacht.
        was genau meinst Du denn mit "Fehlerfall"? Dass die Ressource, die includet werden soll, nicht vorhanden ist? Oder dass aus einem technischen Grund der Include nicht funktioniert hat? Falls letzteres überhaupt möglich ist, dann würde doch die komplette Skriptverarbeitung auch nicht funktionieren. Oder meintest Du mit "Fehlerfall" etwas ganz anderes?

        Fehlerfall ist, wenn das Inkludieren als solches aus welchem Grund auch immer erfolglos war. Das PHP-Handbuch führt an, dass ein Grund eine nicht vorhandenen Datei ist. Vermutlich zählen auch noch fehlende Zugriffsberechtigungen dazu. Fehler beim Parsen zählen extra.

        Der Meinung, include(_once) generell zu vermeiden, wie Sven es einleitend vorschlug, schließe ich mich nicht an. Nicht in jedem Fall will man dem Anwender nur eine PHP-Fehlermeldung oder auch nur einen unbegründeten (wenn display_errors ausgeschaltet ist) Abbruch anbieten. Bei include(_once) hat man zumindest die Möglichkeit mit eigenem Code das Fehlen abzufangen und noch einen geordneten Abschluss hinzulegen. Nun kann das Argument kommen, dass man dann vorher mal ein is_readable() anwenden kann. Kann man - wenn der zweifache Dateisystemzugriff bei jedem Mal billiger ist, als ein @ und das Auswerten hinterher. Das sollte man aber für seine Soituation individuell klären.

        dedlfix.

        1. Moin!

          Weil beides [include/include_once] im Fehlerfall nur eine Warnung produziert und ansonsten weitermacht.
          was genau meinst Du denn mit "Fehlerfall"? Dass die Ressource, die includet werden soll, nicht vorhanden ist? Oder dass aus einem technischen Grund der Include nicht funktioniert hat? Falls letzteres überhaupt möglich ist, dann würde doch die komplette Skriptverarbeitung auch nicht funktionieren. Oder meintest Du mit "Fehlerfall" etwas ganz anderes?

          Fehlerfall ist, wenn das Inkludieren als solches aus welchem Grund auch immer erfolglos war. Das PHP-Handbuch führt an, dass ein Grund eine nicht vorhandenen Datei ist. Vermutlich zählen auch noch fehlende Zugriffsberechtigungen dazu. Fehler beim Parsen zählen extra.

          Der Meinung, include(_once) generell zu vermeiden, wie Sven es einleitend vorschlug, schließe ich mich nicht an. Nicht in jedem Fall will man dem Anwender nur eine PHP-Fehlermeldung oder auch nur einen unbegründeten (wenn display_errors ausgeschaltet ist) Abbruch anbieten. Bei include(_once) hat man zumindest die Möglichkeit mit eigenem Code das Fehlen abzufangen und noch einen geordneten Abschluss hinzulegen. Nun kann das Argument kommen, dass man dann vorher mal ein is_readable() anwenden kann. Kann man - wenn der zweifache Dateisystemzugriff bei jedem Mal billiger ist, als ein @ und das Auswerten hinterher. Das sollte man aber für seine Soituation individuell klären.

          Meine Forderung war, grundsätzlich require() einzusetzen, und include() nur im Ausnahmefall. Ein Ausnahmefall ist genau das, was du beschreibst: Man kann evtl. nicht sicherstellen, dass die Zieldatei zu 100% immer vorhanden ist, und möchte alternativ ein eigenes Fehlerprogramm abspulen. Klassischer Fall: Template-Dateien.

          Aber das Einbinden z.B. von Klassen (egal ob via Autoload oder "normal" explizit) darf nicht scheitern, und ein Alternativprogramm wird an dieser Stelle auch nicht funktionieren. Solche Fehlerzustände sollten allerdings auch nur zur Entwicklungszeit auftreten, und die will man an dieser Stelle nicht unbemerkt lassen, sondern beheben.

          Es kann ja z.B. sein, dass man explizit eine Klasse includet, aber nicht mehr verwendet, und die Datei deshalb auch löscht - nur das (ggf. verteilte) include() nicht, weil man es nicht mehr findet. Diese kaputten Includes kosten ab dann kräftig Ladezeit (der include_path wird komplett nach der nicht mehr existierenden Datei durchsucht) und bringt Verwirrung (ist das Include falsch, oder fehlt die Datei?). Hätte man require() verwendet, würde das Problem nicht entstehen.

          Deshalb lautet mein Rat: Immer require() verwenden, außer man weiß, dass man die fehlertolerantere Variante include() benötigt.

          - Sven Rautenberg