Marion: PHP-Script soll PHP-Script includen

Hallo Ihr,

nach einigen Monaten der Beschäftigung mit ASP habe ich nun PHP entdeckt und befinde mich in einer Art PHP-Rausch. Funktioniert hier doch alles irgendwie "intuitiver" und "pragmatischer". Aber egal. Irgend wie habe ich mich jetzt vergaloppiert. Hier meine Frage:

Mit include() und require() binde ich externe Dateien in eine PHP-Datei ein. Richtig? Nun möchte ich (abhängig von einer vorangegangenen Entscheidung) eine Datei einbinden der Art:

require($ThePath . "TheFile.inc.php");

So weit so gut. Der Wert von $ThePath wurde aus vielen verschiedenen Verzeichnissen ausgewählt und belegt, die Datei TheFile.inc.php gibt es auf allen diesen Verzeichnissen. Nun möchte ich aber _in_ den verschiedenen TheFiles.inc.php auf Bilder zugreifen, deren Speicherort ($TheImagePath) ich an gleicher Stelle ermittelt habe, wie auch $ThePath (drücke ich mich verständlich aus?). Es steht also in TheFile.inc.php die Zeile:

$TheImageString = "<img src="" . $TheImagePath . "TheImageFile.jpg" alt="Image">";

Aber das funktioniert nicht. Die Pfad-Variable wird einfach ignoriert, der Rest wird ausgeführt.

Wie funktioniert das mit dem PHP-Parser? Ist es vielleicht so, dass der Parser mit der Bearbeitung des initialen require() seine Arbeit abgeschlossen hat und sich nicht dafür interessiert, dass in der gerade includeten Datei auch noch Arbeit für ihn wäre? Wie kriege ich mein Problem gelöst?

Vielen Dank an Euch
Marion

  1. Warscheinlich ist $TheImagePath an der nötigen Stelle in 'TheFile.inc.php' nicht mehr im Sichtbarkeitsbereich. Schau dir dazu mal http://www.php.net/manual/de/language.variables.scope.php an. Vielleicht hilft es dir ja weiter.

    Grüsse, Lucien

    1. Hallo,

      Sichtbarkeitsbereich

      stimmt, so was gibt es ja auch noch. In diesem Fall müsste es aber funktionieren.

      Trotzdem Danke für den Link.

      Marion

  2. Hello,

    das geht mit den Magischen Konstanten.

    Schau Dir mal an, wie ich das in http://selfhtml.bitworks.de/artikel_locking/show_visitors.php gemacht habe.

    Harzliche Grüße aus http://www.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau
  3. Moin!

    Der Wert von $ThePath wurde aus vielen verschiedenen Verzeichnissen ausgewählt und belegt...

    $TheImageString = "<img src="" . $TheImagePath . "TheImageFile.jpg" alt="Image">";

    Aber das funktioniert nicht. Die Pfad-Variable wird einfach ignoriert, der Rest wird ausgeführt.

    Ich sehe nirgends, auch nicht von dir erwähnt, dass irgendwo der Inhalt von $ThePath in die Variable $TheImagePath kopiert wurde. Folglich ist die Variable $TheImagePath leer, und "es funktioniert nicht".

    Wie funktioniert das mit dem PHP-Parser?

    An der Stelle, wo im äußeren File die include- oder require-Anweisung steht, wird stattdessen das gesamte referenzierte Include-File eingesetzt und ausgeführt. include() und require() unterscheiden sich nur in ihrem Verhalten bei Fehlern - require() bricht das komplette Skript ab, include() gibt nur eine Fehlermeldung aus.

    Üblich ist es, in Include-Files nur Funktionen oder Klassen zu definieren, die dann von vielen Skripten verwendet werden können. In diesem Zusammenhang wäre es ja fatal, wenn Funktionen mehrfach definiert würden, und es bietet sich dafür die Verwendung von include_once() bzw. require_once() an. Eine bereits eingebundene Datei (egal ob in der aktuellen oder einer "höheren" Ebene) wird dann nicht noch einmal eingebunden - würde bei deiner Anwendungsweise dann aber auch nicht noch einmal ausgeführt. Das hier aber nur zur Vollständigkeit.

    • Sven Rautenberg
    1. Hi Sven,

      Ich sehe nirgends, auch nicht von dir erwähnt, dass irgendwo der Inhalt von $ThePath in die Variable $TheImagePath kopiert wurde. Folglich ist die Variable $TheImagePath leer, und "es funktioniert nicht".

      Ja, das habe ich nicht geschrieben, aber die Variable wird gesetzt. In diesem besonderen Fall, haben beide Pfad-Variable sogar den gleichen Wert.

      Üblich ist es, in Include-Files nur Funktionen oder Klassen zu definieren, die dann von vielen Skripten verwendet werden können.

      Tja, deshalb bist Du auch PHP-Professional und ich Anfängerin :-) Ich habe keine Ahnung was da üblich ist, sehe nur die Mittel und Möglichkeiten und wurschtle drauf los (=> PHP-Rausch!).

      Den Fehler habe ich inzwischen gefunden. Es war ein saudummer Fehler. Die Scripts und die Includes machen genau was ich will. Allerdings habe ich dieses require()-Konstrukt nicht (wie beschrieben) einmal sondern mehrfach in verschiedenen Varianten in der äußeren Datei geschrieben. Und durch einen Copy/Paste Flüchtigkeitsfehler hat es mir die Variable $TheImageString im nächsten require() einfach überschrieben. Deshalb konnte ich im ersten require() Script schreiben was ich wollte, es wurde im Folgescript immer egalisiert.

      Trotzdem Danke für Deine Mühe
      Marion

      PS: Wie machen das eigentlich die PHP-Professionals mit der Fehlersuche. Ich gebe zum debuggen per echo-Befehl völlig chaotisch irgend welche Werte aus, nehme in Kauf, dass das ganze Script abnippelt und sehe mir dann die Sourcen über einen Browser an, der zumindest noch meine Debug-Meldung ausgegeben hat, bevor er sich verabschiedet. Gibt es da vernünftige Simulations- oder Debug-Umgebungen für PHP?

      1. Moin!

        PS: Wie machen das eigentlich die PHP-Professionals mit der Fehlersuche. Ich gebe zum debuggen per echo-Befehl völlig chaotisch irgend welche Werte aus, nehme in Kauf, dass das ganze Script abnippelt und sehe mir dann die Sourcen über einen Browser an, der zumindest noch meine Debug-Meldung ausgegeben hat, bevor er sich verabschiedet. Gibt es da vernünftige Simulations- oder Debug-Umgebungen für PHP?

        Es gibt PHP-Entwicklungsumgebungen, die wohl diverse nette Features bieten, das laufende bzw. angehaltene PHP-Skript inklusive seiner Variablen zu "bearbeiten".

        Ich benutze sowas aber nicht, kann folglich auch keine Empfehlungen geben, ob das toll ist. Ich empfehle aber ganz unabhängig davon, dass du dir sämtliche Fehler inklusive der Notice-Meldungen (die sind eigentlich die wichtigsten, weil sie subtile Fehlerquellen aufdecken) anzeigen läßt: error_reporting(E_ALL) im Skript bzw. die passende Option in der php.ini setzen.

        Damit die Fehlermeldungen die HTML- oder sonstige Skriptausgabe (PHP kann ja z.B. auch Bilder generieren) nicht stört, kann man sich die Fehler auch in eine Logdatei ausgeben lassen und die (zumindest unter Linux) problemlos während des Skriptaufrufs beobachten ("tail -f logfile" macht das unter Linux - Windows bietet sowas leider nicht standardmäßig an - und es ist ein Shellzugang für sowas erforderlich).

        Und den Rest hast du im Prinzip schon richtig erkannt: Wenn irgendwas nicht so läuft, wie man es sich denkt, sollte man in der Tat irgendwelche Kontrollausgaben vornehmen und gucken, ob die denn den eigenen Erwartungen und Annahmen entsprechen, oder nicht. So gehen auch Profis vor - wobei die vielleicht besser wissen, was sie zu kontrollieren haben. Hierbei helfen insbesondere die Funktionen var_dump und print_r - die zeigen nicht nur den Variableninhalt an, sondern auch problemlos ganze Arrays, und sie zeigen den Variablentyp mit an.

        Außerdem ganz wichtig: PHP-Fehlermeldungen geben immer Hinweise darauf, was genau falsch ist. Deshalb sollte man diese unbedingt lesen, ggf. übersetzen, wortwörtlich in Google suchen lassen (Anführungszeichen drumrum machen für Phrasensuche) und mit dem so gewonnenen Wissen zielgerichtet Gegenmaßnahmen ergreifen. Und keinesfalls "Hilfe, mein Skript geht nicht!" in irgendeinem Forum rufen, ohne die Fehlermeldung mit hinzuschreiben. :)

        • Sven Rautenberg
        1. Hallo Sven,

          alles klar! Danke!

          Marion

        2. Hello,

          die Frage nach dem Pfad oder einer Variablen dafür (die ich mir auch selber schon oft gestellt hatte) hat bei mir nun noch eine andere Frage aufgeworfen:

          Wenn man nun nicht mit Klassen arbeitet, die includet werden, sondern "nur" mit externen Dateien, dann hat man ja keine Abgrenzug der Namesräume. Wie könnte man die denn am sinnvollsten gestalten für das Include von einfachen Dateien? Alles, was darin entahltene Funktionen un deren Innenleben betrifft, ist ja mehr oder weniger geschützt. Bei Namensdoublette einer Funktion gibts 'nen Fehler, bei Namensdoubletten von funktionsintern benutzten Namen greift die Abgrenzung der Namensräume.

          Was macht man aber am sinnvollsten mit den Variablen der Datei, die außerhalb stehen?

          Die müsste man ja sinnvollerweise in zwei Gruppen einteilen:

          - Variablen, die nur für die eingebundene Datei zuständig sind
            - Variablen, die als "Export" für das gesamte Script gelten.

          Wie würdest Du das sinnvoll gestalten? Wie gesagt, nicht als Klasse, sondern klassisch ;-))

          Harzliche Grüße aus http://www.annerschbarrich.de

          Tom

          --
          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
          Nur selber lernen macht schlau
          1. Moin!

            Wenn man nun nicht mit Klassen arbeitet, die includet werden, sondern "nur" mit externen Dateien, dann hat man ja keine Abgrenzug der Namesräume. Wie könnte man die denn am sinnvollsten gestalten für das Include von einfachen Dateien?

            Einfach ganz furchtbar gut aufpassen. Den Transfer von Variablen über Include-Grenzen auf ein Minimum reduziert halten könnte helfen.

            Wie würdest Du das sinnvoll gestalten? Wie gesagt, nicht als Klasse, sondern klassisch ;-))

            Ich habe eine Shop-Software entwickelt, die an genau einer Stelle das hier angesprochene Problem entwickeln könnte: Eine zentrale Datei "shop.php", auf die mit mod_rewrite alle Requests umgeleitet werden, analysiert die angeforderte URL und verzweigt dann entsprechend zu diversen Unterdateien, welche dann die gewünschten Daten per Klassenmethode anfordern, ins Template einsetzen und ausgeben. Damit ich in der "shop.php" nicht ellenlange "if-else" oder "switch-case"-Bedingungen habe, wird der auszuführende Code des jeweiligen Falls mit include eingebunden. Der Transfer von Variablen ist an dieser Stelle allerdings Null, da zuerst nur (mit statischem Methodenaufruf einer weiteren Klasse) die URL analysiert wurde - alle anderen Prozeduren wie Artikelliste holen oder Warenkorb ausgeben aber erst in der eingebundenen Datei stattfinden.

            Es gibt in der Tat keine Lösung, um Konflikten an dieser Stelle durch Namensräume aus dem Weg zu gehen - sie treten einfach auf, wenn man nicht aufpaßt. Dasselbe Problem hat man ja auch, wenn man ein sehr sehr langes Skript mit ganz viel "Hauptprogramm" schreibt und am Ende aus Versehen eine Variable benutzt, die am Anfang schon eine wichtige Funktion hatte.

            • Sven Rautenberg
          2. echo $begrueszung;

            Was macht man aber am sinnvollsten mit den Variablen der Datei, die außerhalb stehen?

            Man könnte daraus eine Funktion mit statischer loakler Variable machen, dann gibt es wenigstens eine Fehlermeldung bei Namensgleichheit:

            function &variable($value = null) {

            static $variable = null;

            // evtl. Schreibzugriff
              if ($value != null)
                $variable = $value;

            // Lesezugriff
              return $variable;
            }

            Ob die Funktion eine Referenz oder eine Kopie zurückgeben soll, musst du selbst entscheiden...

            echo "$verabschiedung $name";