Melvin Cowznofski: Variablen bei include_once()

Hallo,

ich habe gerade ein Phänomen festgestellt, das ich mir nicht erklären kann.
Gegeben sei folgende Situation im Wurzelverzeichnis der Domain www.example.com:

Im Ordner "test2" liegt folgende "index.php":

<?php  
  $variable = 'foo';  
  include_once('../test3/file.php');  
?>

Im Ordner "test3" liegt die Ressource "file.php":

<?php  
  var_dump($variable);  
?>

Wenn ich nun www.example.com/test2 aufrufe, erscheint das, was ich erwarte: string(3) "foo"
So weit, so gut. Nun ändere ich die index.php und mache aus der relativen eine absolute Pfadangabe:

<?php  
  $variable = 'foo';  
  include_once('www.example.com/test3/file.php');  
?>

Wenn ich die Seite jetzt erneut aufrufe, liefert mir die Variablenüberprüfung ein NULL.

Und das verstehe ich nicht. Die Variable ist sicher gesetzt. Das sehe ich, wenn ich am Ende der "index.php" ein 2. var_dump() setze. Und die "file.php" wird auch sicher eingefügt. Das erkenne ich, wenn ich noch irgend ein echo"..." dazugebe. Es wäre also wie im 1. Fall alles da!

Wieso erkennt die eingebettete Ressource die bestehende Variable nur bei relativer, aber nicht bei absoluter Pfadangabe? Kann mir das bitte wer in verständlichen Worten erklären?

Mit lieben Grüßen und bestem Dank im Voraus

Melvin Cowznofski

--

Melvin Cowznofski
What – me worry?
  1. Hi,

    Nun ändere ich die index.php und mache aus der relativen eine absolute Pfadangabe:

    <?php

    $variable = 'foo';
      include_once('www.example.com/test3/file.php');
    ?>

      
    das ist keine absolute Pfadangabe. Es ist eine relative Pfadangabe, die mit dem Verzeichnis www.example.com beginnt, ausgehend vom Verzeichnis des übergeordneten Scripts.  
      
    
    > Wenn ich die Seite jetzt erneut aufrufe, liefert mir die Variablenüberprüfung ein NULL.  
      
    Natürlich, weil die include-Datei nicht gefunden wird. Das würde dir PHP aber mit einem geeignet eingestellten error\_reporting (E\_ALL wäre während Entwicklung und Debugging sinnvoll) auch unmissverständlich mitteilen.  
      
    Ciao,  
     Martin  
    
    -- 
    [Ich bin im Prüfungsstress](http://community.de.selfhtml.org/zitatesammlung/zitat436), ich darf Scheiße sagen.  
      (Hopsel)  
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    
    1. Hallo Martin!

      das ist keine absolute Pfadangabe. Es ist eine relative Pfadangabe, die mit dem Verzeichnis www.example.com beginnt, ausgehend vom Verzeichnis des übergeordneten Scripts.

      Ups, das war nur ein Schlampigkeisfehler beim Posten!
      Selbstverständlich ist

      <?php  
        $variable = 'foo';  
        include_once('http://www.example.com/test3/file.php');  
      ?>
      

      gemeint! Darum sagte ich ja auch absolute Pfadangabe!

      Natürlich, weil die include-Datei nicht gefunden wird.

      Ich _sagte_ doch, sie wird gefunden! Nur die Variable übernimmt sie nicht.
      Also es bleibt bei der Frage: Kann mir wer erklären, wieso das so ist?

      Mit lieben Grüßen

      Melvin Cowznofski

      --

      Melvin Cowznofski
      What – me worry?
      1. Hi,

        Selbstverständlich ist

        <?php

        $variable = 'foo';
          include_once('http://www.example.com/test3/file.php');
        ?>

        
        >   
        > gemeint!  
          
        Was ist daran selbstverständlich? Includes per http sind äußerst ungewöhnlich.  
          
        
        > Ich \_sagte\_ doch, sie wird gefunden!  
          
        Was der Fragesteller \*sagt\*, hat häufig wenig oder nichts mit der Realität zu tun.  
          
        Du hast z.B. von einer absoluten Pfadangabge gesprochen, aber tatsächlich ging es nicht um eine absolute Pfadangabe, sondern um eine URL.  
          
        
        > Nur die Variable übernimmt sie nicht.  
          
        Dann denk darüber nach, was passiert, wenn das zu inkludierende per HTTP abgerufen wird:  
          
        Vom Webserver wird http://www.example.com/test3/file.php verlangt.  
        Aufgrund der Endung .php wird nicht die Datei selbst, sondern das Ergebnis des PHP-Scripts ausgeliefert.  
        Und während das läuft, ist die Variable nicht definiert.  
          
        Includiert wird dann das, was vom var\_dump ausgegeben wird.  
          
        cu,  
        Andreas
        
        -- 
        [Warum nennt sich Andreas hier MudGuard?](http://MudGuard.de/)  
        [O o ostern ...](http://ostereier.andreas-waechter.de/)  
          
        Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.  
        
        
        1. Hello,

          Selbstverständlich ist

          <?php

          $variable = 'foo';
            include_once('http://www.example.com/test3/file.php');
          ?>

          
          > >   
          > > gemeint!  
          >   
          > Was ist daran selbstverständlich? Includes per http sind äußerst ungewöhnlich.  
            
          Includes per http oder aus sonstigen externen Quellen sind \_äußerst\_\_gefährlich\_, aber leider nicht selten und damit auch nicht "ungewöhnlich" ;-P  
            
          Zum Glück sind die Wrapper für Includes meistens ausgeschaltet.  
            
          <http://de3.php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen>  
            
          Wir hatten ja hier einige Threads zu Angriffs-Szenarios. Diese Option stellt eine Grundlage dafür dar.  
            
            
            
            
            
            
            
          Liebe Grüße aus dem schönen Oberharz  
            
            
          Tom vom Berg  
          ![](http://selfhtml.bitworks.de/Virencheck.gif)  
            
          
          -- 
           ☻\_  
          /▌  
          / \ Nur selber lernen macht schlau  
          <http://bikers-lodge.com>
          
        2. Hallo Andreas,

          Vom Webserver wird http://www.example.com/test3/file.php verlangt.
          Aufgrund der Endung .php wird nicht die Datei selbst, sondern das Ergebnis des PHP-Scripts ausgeliefert.
          Und während das läuft, ist die Variable nicht definiert.
          Includiert wird dann das, was vom var_dump ausgegeben wird.

          Ja, natürlich! Jetzt, wo Du es sagst! Eh klar! Ich sah den Wald vor lauter Bäumen nicht...

          Vielen Dank!

          Mit lieben Grüßen

          Melvin Cowznofski

          --

          Melvin Cowznofski
          What – me worry?
      2. Moin!

        das ist keine absolute Pfadangabe. Es ist eine relative Pfadangabe, die mit dem Verzeichnis www.example.com beginnt, ausgehend vom Verzeichnis des übergeordneten Scripts.

        Ups, das war nur ein Schlampigkeisfehler beim Posten!
        Selbstverständlich ist

        <?php

        $variable = 'foo';
          include_once('http://www.example.com/test3/file.php');
        ?>

        
        >   
        > gemeint! Darum sagte ich ja auch absolute Pfadangabe!  
          
        Das ist aber kein Dateisystempfad, sondern eine URL. Und dieser Unterschied ist entscheidend.  
          
        
        > > Natürlich, weil die include-Datei nicht gefunden wird.  
        >   
        > Ich \_sagte\_ doch, sie wird gefunden! Nur die Variable übernimmt sie nicht.  
        > Also es bleibt bei der Frage: Kann mir wer erklären, wieso das so ist?  
          
        Bei deinem ersten Versuch liest PHP über das Dateisystem den Inhalt der Datei ein und führt den Code aus.  
          
        Beim zweiten Versuch liest PHP eine externe Ressource ein. Dies führt zu einem HTTP-Request auf deinen eigenen Server, der in einem neuen Kontext lediglich das Script in test3 ausführt. Variablen werden hierbei NICHT übergeben.  
          
        Das Ergebnis eines schlichten "var\_dump($undefinierte\_variable)" ist der Text "NULL". (Und eigentlich sollte in Entwicklungsumgebungen auch noch ein Notice-Text dabei sein...)  
          
        Das Includieren von schlichtem HTML-Text gibt diesen lediglich aus. Dein Skript in Test2 bindet also keinen PHP-Code ein, sondern sozusagen HTML-Code.  
          
        Es ist immer extrem wichtig, dass man PHP-Codeeinbindungen NIE über HTTP-Zugriffe vornimmt. Eines der wichtigen Features gut konfigurierter Webserver ist, dass man als Nutzer von außen nicht jedes beliebige PHP-Skript aufrufen kann. Insofern ist es nur natürlich, dass PHP innerhalb des Webservers mit Zugriffen via Dateisystem mehr darf, als man von außen via URL erreichen kann.  
          
        Vor allem kann man eben nicht "einfach" PHP-Code via URL so einbinden, dass dieser im Kontext des einbindenden Skripts ausgeführt wird. Hierzu müsste man den PHP-Interpreter beim Aufruf des anderen Skripts deaktivieren, um an den Quellcode zu gelangen. Damit programmiert man sich aber gleich die extremste Sicherheitslücke, denn niemand sollte via HTTP-Zugriff an die Quellcodes der PHP-Skripte kommen.  
          
        Relative Pfadangaben sind ok. Jedes PHP-Skript kennt auch die magische Konstante \_\_FILE\_\_ und ab PHP 5.3 auch \_\_DIR\_\_, in denen der Dateinamen des aktuellen Skripts bzw. der Verzeichnisname enthalten sind. Diese Angabe zusammen mit einer relativen Pfadangabe sind zuverlässige Pfadangaben im Dateisystem.  
          
         - Sven Rautenberg
        
        1. Hallo Sven,

          Vielen Dank für Deine ausführliche Antwort!

          Ich habe eh schon weiter unten geschrieben: In dem Moment, als ich Andreas Antwort gelesen habe, war es mir sofort klar. War ein gedankliches Blackout. Vielleicht sollte ich mal eine Pause machen. =)

          Mit lieben Grüßen

          Melvin Cowznofski

          --

          Melvin Cowznofski
          What – me worry?
        2. Hello,

          Vor allem kann man eben nicht "einfach" PHP-Code via URL so einbinden, dass dieser im Kontext des einbindenden Skripts ausgeführt wird. Hierzu müsste man den PHP-Interpreter beim Aufruf des anderen Skripts deaktivieren, um an den Quellcode zu gelangen. Damit programmiert man sich aber gleich die extremste Sicherheitslücke, denn niemand sollte via HTTP-Zugriff an die Quellcodes der PHP-Skripte kommen.

          Viel, viel schlimmer ist es aber noch, wenn die über URL-Wrapper zum Include beschaffte Ressource von einem externen Server kommt.

          Dann kann man den Server gleich auf die Straße stellen.

          Liebe Grüße aus dem schönen Oberharz

          Tom vom Berg

          --
           ☻_
          /▌
          / \ Nur selber lernen macht schlau
          http://bikers-lodge.com