Relative Verlinkung / Include
meisterether
- php
Hallo.
Ich hab' zwei PHP-Dateien in unterschiedlichen Verzeichnissen (eine im Stammverzeichnis, die andere in 'nem Unterordner). Beide inkludieren eine dritte, ebenfalls im Stammverzeichnis befindliche PHP-Datei, die nur ein Baustein für beide sein soll und ein Bild mit relativer Verlinkung (in einen anderen Unterordner) enthält.
Das Inkludieren der dritten Datei in die beiden anderen ist (so weit) nicht das Problem. In Datei Nr. 1 funktioniert auch alles. Nur wird das Bild (der dritten Datei aus dem Stammverzeichnis) in der anderen PHP-Datei (aus dem Unterverzeichnis) nicht angezeigt, da sich die zu inkludierende Datei ursprünglich ja nur an der ersten orientieren musste. In der Datei im Unterverzeichnis bekommt das Bild durch die relative Verlinkung also einen falschen Pfad:
"/root/Unterverzeichnis/bilder/bild.jpg", wobei "/root/bilder/bild.jpg" ja richtig wäre. Die zu inkludierende Datei soll IM Unterverzeichnis also NICHT den Unterverzeichnis-Weg benutzen, sondern bleiben und handeln, wo sie ist.
Wie kann ich das Problem lösen, ohne großartig Pfadangaben ändern zu müssen? Oder gibt's 'nen Befehl, den ich vor das Include in der Unterverzeichnis-Datei setzen könnte? Bzw. hab' ich von "include_once" und "require" und sowas gelesen, falls die hilfreich sein könnten, aber leider keine Ahnung, was diese Befehle können. :)
Mit bestem Dank im Voraus,
meisterether
p.s.: Ich hab' von PHP kaum 'ne Ahnung und die ganzen Dateien sind natürlich etwas komplexer, aber das oben Genannte ist das grundlegende Problem dabei.
Grüße,
es gibt leider keine saubere lösung - du musst wohl mit absoluten pfadangaben arbeiten, oder diese dynamisch erzeugen lassen.
MFG
bleicher
P.S: oder mit <base href=""> versuchen?
MFG
bleicher
Hallo.
Wie kann ich das Problem lösen, ohne großartig Pfadangaben ändern zu müssen?
Oder gibt's 'nen Befehl, den ich vor das Include in der Unterverzeichnis-Datei setzen könnte? Bzw. hab' ich von "include_once" und "require" und sowas gelesen, falls die hilfreich sein könnten, aber leider keine Ahnung, was diese Befehle können. :)
Wenn Du nicht weisst, was sie bedeuten, dann schau es doch mal nach. Die werden Dir hier aber nicht helfen.
Ich wuerds so machen: in jeder Deiner Seiten setzt Du eine Variable $root (am Anfang des Skripts, bevor Du die Includes machst), die den relativen Pfad zu Deinem Rootverzeichnis beinhaltet. Im Rootverzeichnis selber waere das also '$root = "./";', im Unterverzeichnis waere es '$root = "../";'
Die Variable $root hast Du dann jeweils in der inkludierten Datei zur Verfuegung, damit ist das Ganze kein Problem.
Gruss
der Bademeister
Hallo
Ich hab' zwei PHP-Dateien in unterschiedlichen Verzeichnissen (eine im Stammverzeichnis, die andere in 'nem Unterordner). Beide inkludieren eine dritte, ebenfalls im Stammverzeichnis befindliche PHP-Datei, die nur ein Baustein für beide sein soll und ein Bild mit relativer Verlinkung (in einen anderen Unterordner) enthält.
Es geht um ein Stück HTML-Code, das in mehreren Seiten benutzt wird?
"/root/Unterverzeichnis/bilder/bild.jpg", wobei "/root/bilder/bild.jpg" ja richtig wäre.
Ist es ja auch. Wenn das Bild als /grafik/bild.png zu finden ist, also im Verzeichnis "Grafik" direkt unterhalb der "DOCUMENT ROOT" liegt, kannst du sie im src-Attribut von <img> direkt und in _jedem_ Unterverzeichnis der Domain mit "/grafik/bild.png" einbinden. Gleiches gilt z.B. auch für CSS- oder JavaScript-Ressourcen.
Tschö, Auge
Hallöchen,
Wie kann ich das Problem lösen, ohne großartig Pfadangaben ändern zu müssen? Oder gibt's 'nen Befehl, den ich vor das Include in der Unterverzeichnis-Datei setzen könnte? Bzw. hab' ich von "include_once" und "require" und sowas gelesen, falls die hilfreich sein könnten, aber leider keine Ahnung, was diese Befehle können. :)
$OrdnerMitBildern = 'bilder/';
for($i=0; $i<5; $i++) { // die 5 beschränkt die Suche auf 5 Ebenen aufwärts
if(!is_dir($OrdnerMitBildern)) {
$OrdnerMitBildern='../'.$OrdnerMitBildern;
}
else {
break;
}
}
<img src="<?php echo $OrdnerMitBildern.'MeinBild.gif'; ?>" width="xxx" height="yyy" border="0">
Lesen - Verstehen - Anwenden ;)
Bei manchen Funktionen ist nämlich relative Pfadangabe zwingend erforderlich...
MfG
vaudi
Hallo
$OrdnerMitBildern = 'bilder/';
for($i=0; $i<5; $i++) { // die 5 beschränkt die Suche auf 5 Ebenen aufwärts
if(!is_dir($OrdnerMitBildern)) {
$OrdnerMitBildern='../'.$OrdnerMitBildern;
}
else {
break;
}
}<img src="<?php echo $OrdnerMitBildern.'MeinBild.gif'; ?>" width="xxx" height="yyy" border="0">
> Lesen - Verstehen - Anwenden ;)
>
> Bei manchen Funktionen ist nämlich relative Pfadangabe zwingend erforderlich...
Beispiel(e)? Genau bei Pfadangaben im HTTP-Kontext (es gibt eine DOCUMENT ROOT) ist sie \_nicht\_ notwendig.
Tschö, Auge
--
Die deutschen Interessen werden am Liechtenstein verteidigt.
[Veranstaltungsdatenbank Vdb 0.2](http://termindbase.auge8472.de/)
Hallöchen,
Beispiel(e)? Genau bei Pfadangaben im HTTP-Kontext (es gibt eine DOCUMENT ROOT) ist sie _nicht_ notwendig.
Im Zusammenhang mit reinem HTML ist die startordner-relative Angabe auch meiner Meinung nach prinzipiell vorzuziehen.
Sobald es aber mit PHP z.B. an Funktionen des Dateisystems geht, sind oft dokument-relative Pfadangaben notwendig. Genauso erfordert z.B. include eine dokument-relative Angabe.
Ich hab bei meinem Webhoster die Möglichkeit, Dateien mit sensiblen Daten (z.B. Datenbank-Login) in einem Ordner abzulegen, der per Browser nicht zugänglich ist. Dazu muss ich beim include einen dokument-relativen Pfad nehmen, der eine Ebene höher führt als die index-Datei gespeichert ist. Und um nicht bei jeder Seite zu überprüfen, ob dieser Pfad stimmt, nehme ich die gepostete Funktion. Damit kann ich mein Template auf der gesamten Website ohne Anpassung einsetzen - außer es läge tiefer als 4 Verzeichnisebenen.
MfG
vaudi
Hallo
Beispiel(e)? Genau bei Pfadangaben im HTTP-Kontext (es gibt eine DOCUMENT ROOT) ist sie _nicht_ notwendig.
Im Zusammenhang mit reinem HTML ist die startordner-relative Angabe auch meiner Meinung nach prinzipiell vorzuziehen.
Genau diesen Fall nehme ich nach den Einlassungen des OP an.
Ich hab bei meinem Webhoster die Möglichkeit, Dateien mit sensiblen Daten (z.B. Datenbank-Login) in einem Ordner abzulegen, der per Browser nicht zugänglich ist. Dazu muss ich beim include einen dokument-relativen Pfad nehmen, der eine Ebene höher führt als die index-Datei gespeichert ist.
Benutze _immer_ den absoluten Pfad im Dateisystem, um deine Includes zu laden ...
Und um nicht bei jeder Seite zu überprüfen, ob dieser Pfad stimmt, ...
... und du musst nicht immer wieder überprüfen, wieviele Verzeichnisebenen höher oder tiefer du bist.
Tschö, Auge
Hallöchen,
Benutze _immer_ den absoluten Pfad im Dateisystem, um deine Includes zu laden ...
Beschreibung zu include():
Dateien die mit include eingebunden werden, werden zuerst im include_path relativ zum gegenwärtigen Arbeitsverzeichnis gesucht und danach im include_path relativ zum Verzeichnis des ausgeführten Skripts.
Also ich lese da was von "include_path relativ zum Verzeichnis". Und die Erfahrung hat bewiesen: wenn ich mich nicht dran halte, funktioniert es nicht.
MfG
vaudi
echo $begrüßung;
Beschreibung zu include():
Tipp: Wenn du etwas anhand des Handbuchs zu beweisen versuchst, verwende das englische Original, nicht die deutsche Übersetzung. Dann hast du größere Chancen auf eine korrekte Beschreibung zu treffen.
Dateien die mit include eingebunden werden, werden zuerst im include_path relativ zum gegenwärtigen Arbeitsverzeichnis gesucht und danach im include_path relativ zum Verzeichnis des ausgeführten Skripts.
Im Gegensatz dazu der Originaltext:
Files for including are first looked for in each include_path entry relative to the current working directory, and then in the directory of current script.
Das "im include_path relativ zum Verzeichnis" muss nur "relativ zum Verzeichnis" lauten. Dann stimmt es mit dem tatsächlichen Verhalten PHPs überein.
Auch im restlichen Text dieses Absatzes ist noch ein gravierender Fehler enthalten:
Deutsch: Beginnt der Pfad mit ../ so wird der include_path nur relativ zum aktuellen Verzeichnis durchsucht.
Original: If filename begins with ./ or ../, it is looked only in the current working directory.
Das bezog sich aber alles nur auf relative Angaben. Man kann natürlich auch absolute Angaben machen, dann beziehen sich diese aber auf das Filesystem, nicht aber etwa auf das DocumentRoot.
echo "$verabschiedung $name";
Hallöchen,
Tipp: Wenn du etwas anhand des Handbuchs zu beweisen versuchst, verwende das englische Original, nicht die deutsche Übersetzung. Dann hast du größere Chancen auf eine korrekte Beschreibung zu treffen.
OK, werd prinzipiell versuchen mich dran zu halten. Wobei dann allerdings das Problem der Fremdsprache hinzukommt:
Do you speak english? (Sprichst du englisch?)
Oh yes, a paar broken. (Oh ja, ein paar Brocken.)
Bin dankbar für jeden Hinweis. Aber nicht für alles offen (Wer für alles offen ist, kann nicht ganz dicht sein ;).
MfG
vaudi
PS: mein Englisch ist ganz gut...
Hallo.
mein Englisch ist ganz gut...
Meines auch. Dumm nur, wenn jeder sein eigenes hat.
MfG, at
Hallöchen,
Noch was:
Ich hab bei meinem Webhoster die Möglichkeit, Dateien mit sensiblen Daten (z.B. Datenbank-Login) in einem Ordner abzulegen, der per Browser nicht zugänglich ist. Dazu muss ich beim include einen dokument-relativen Pfad nehmen, der eine Ebene höher führt als die index-Datei gespeichert ist.
Benutze _immer_ den absoluten Pfad im Dateisystem, um deine Includes zu laden ...
Beim genaueren Lesen müsste auffallen, dass ich auf Dateien oberhalb der DOCUMENT ROOT der Website zugreife:
Wie sollte ich jetzt anders als mit '../Ordner für includes/daten.inc.php' zugreifen?
'/daten.inc.php' sucht in 'Ordner für Website/'
'/Ordner für includes/daten.inc.php' sucht in 'Ordner für Website/Ordner für includes/'
... womit wir exakt beim anfänglich beschriebenen Problem wären.
MfG
vaudi
echo $begrüßung;
Ich hab bei meinem Webhoster die Möglichkeit, Dateien mit sensiblen Daten (z.B. Datenbank-Login) in einem Ordner abzulegen, der per Browser nicht zugänglich ist. Dazu muss ich beim include einen dokument-relativen Pfad nehmen, der eine Ebene höher führt als die index-Datei gespeichert ist.
Benutze _immer_ den absoluten Pfad im Dateisystem, um deine Includes zu laden ...
Den absoluten Pfad, sollte man nicht jeder include-Anweisung einzeln spendieren sondern im include_path setzen (set_include_path()).
Beim genaueren Lesen müsste auffallen, dass ich auf Dateien oberhalb der DOCUMENT ROOT der Website zugreife:
- oberstes Verzeichnis mit FTP-Zugriff
'- Ordner für Website
' '- index.php
'- Ordner für includes
'- daten.inc.phpWie sollte ich jetzt anders als mit '../Ordner für includes/daten.inc.php' zugreifen?
Ermittle den absoluten Pfad für "oberstes Verzeichnis mit FTP-Zugriff", erweitere ihn um "Ordner für includes", und stell deinen include_path ein. Den Pfad kannst du fest im Script notieren oder mittels $_SERVER['DOCUMENT_ROOT'] (sofern vorhanden), der Konstante __FILE__, $_SERVER['SCRIPT_FILENAME'], $_SERVER['SCRIPT_NAME'], dem Namen des "Ordners für Website" und etwas Stringarithmetik berechnen. (Nicht alle Angaben werden gebraucht, aber das sind die, die man sich näher ansehen sollte. Bitte auch das Verhalten dieser Werte bei mod_rewrite-Verwendung testen.)
'/daten.inc.php' sucht in 'Ordner für Website/'
'/Ordner für includes/daten.inc.php' sucht in 'Ordner für Website/Ordner für includes/'
Nein, das sucht aufgrund des vorangehenden / im Wurzelverzeichnis des Dateisystems.
echo "$verabschiedung $name";
Hallöchen,
Den absoluten Pfad, sollte man nicht jeder include-Anweisung einzeln spendieren sondern im include_path setzen (set_include_path()).
Das man den include_path per script setzen kann, war mir so nicht bewußt. Dachte das ist dem Provider vorbehalten, weil dieser i.d.R. keinen Zugriff auf die php.ini gestattet.
Ermittle den absoluten Pfad für "oberstes Verzeichnis mit FTP-Zugriff", erweitere ihn um "Ordner für includes", und stell deinen include_path ein. Den Pfad kannst du fest im Script notieren oder mittels $_SERVER['DOCUMENT_ROOT'] (sofern vorhanden), der Konstante __FILE__, $_SERVER['SCRIPT_FILENAME'], $_SERVER['SCRIPT_NAME'], dem Namen des "Ordners für Website" und etwas Stringarithmetik berechnen. (Nicht alle Angaben werden gebraucht, aber das sind die, die man sich näher ansehen sollte. Bitte auch das Verhalten dieser Werte bei mod_rewrite-Verwendung testen.)
Probier ich beim nächsten Script aus.
Wenn allerdings
a) ich den Pfad sowieso wieder zu Anfang jedes Scripts ermitteln muss
b) ich mich nicht drauf verlassen kann, dass $_SERVER['DOCUMENT_ROOT'] vorhanden ist
c) es möglich ist, dass das Ganze an mod_rewrite scheitert
kann ich auch gleich bei meiner derzeitigen Lösung bleiben.
MfG
vaudi
echo $begrüßung;
Das man den include_path per script setzen kann, war mir so nicht bewußt. Dachte das ist dem Provider vorbehalten, weil dieser i.d.R. keinen Zugriff auf die php.ini gestattet.
Zu jeder php.ini-Direktive ist in der Spalte Changeable angegeben, wo sie geändert werden kann.
Wenn allerdings
b) ich mich nicht drauf verlassen kann, dass $_SERVER['DOCUMENT_ROOT'] vorhanden ist
$_SERVER['DOCUMENT_ROOT'] ist beispielsweise bei einer CGI-Anbindung nicht vorhanden, wenn es der Provider nicht anderweitig hinzugebracht hat.
c) es möglich ist, dass das Ganze an mod_rewrite scheitert
Scheitern wird es nicht. Ich merke mir nur nie, welche Werte in $_SERVER sich unter welchen Umständen ändern (Hinzufügen von GET-Parametern, URL-Fälscherei bei mod_rewrite). Deswegen kann ich nicht genau sagen, welcher Wert immer genommen werden kann, sondern bitte das selbst auszuprobieren.
a) ich den Pfad sowieso wieder zu Anfang jedes Scripts ermitteln muss
kann ich auch gleich bei meiner derzeitigen Lösung bleiben.
Du kannst außerdem herausfinden, welche Konfigurationsmöglichkeiten dir dein Provider einräumt. Manche haben PHP als Apache-Modul laufen und gestatten in der Per-Verzeichnis-Konfigurationsdatei (meist .htaccess) Änderungen der php.ini-Direktiven. Andere haben CGI und da kannst du eine eigene php.ini ins Script-Startverzeichnis legen (die dann die Providervorgabe komplett aufhebt).
echo "$verabschiedung $name";
Hallo
b) ich mich nicht drauf verlassen kann, dass $_SERVER['DOCUMENT_ROOT'] vorhanden ist
$_SERVER['DOCUMENT_ROOT'] ist beispielsweise bei einer CGI-Anbindung nicht vorhanden, wenn es der Provider nicht anderweitig hinzugebracht hat.
Aha, ich habe mich bisher auch immer auf das Vorhandensein von DOCUMENT_ROOT verlassen. Mit den Magischen Konstanten ergibt sich aber ein Umweg, um den lokalen Pfad zu seinem Webspace zu ermitteln. Oder sollte man sich doch darauf verlassen können, dass die DOCUMENT_ROOT auf jeden Fall in _irgendeiner_ Umgebungs- oder Servervariable über phpinfo()
zu finden ist?
Davon abgesehen lässt sich dieser Pfad ja auch anders ermitteln (und wenn's die Nachfrage beim Hoster ist) und eine selbst angelegte Variable oder Konstante, die vor die Pfade zu den Includes geschnallt wird, ist ja auch kein Problem.
Tschö, Auge
echo $begrüßung;
$_SERVER['DOCUMENT_ROOT'] ist beispielsweise bei einer CGI-Anbindung nicht vorhanden, wenn es der Provider nicht anderweitig hinzugebracht hat.
Aha, ich habe mich bisher auch immer auf das Vorhandensein von DOCUMENT_ROOT verlassen.
Eine kurze Recherche in den öffentlich verfügbaren phpinfo()s lässt mich zu dem Schluss kommen - und da muss ich meine obige Aussage korrigieren - dass der Apache das DOCUMENT_ROOT wohl auch bei CGI-Anbindung mitliefert. Der IIS kennt DOCUMENT_ROOT aber nicht.
echo "$verabschiedung $name";
Hallo
Eine kurze Recherche in den öffentlich verfügbaren phpinfo()s lässt mich zu dem Schluss kommen ... dass der Apache das DOCUMENT_ROOT wohl auch bei CGI-Anbindung mitliefert.
Hatte mich schon gewundert, dass selbst die PHP-Doku bei der Aufzählung typischer Servervariablen[1] darauf nicht hinweist.
Der IIS kennt DOCUMENT_ROOT aber nicht.
Dafür von mir ein herzliches "pffft, und nu?". ;-)
[1] Auch wenn da explizit steht: "Es kann sein, dass Sie die folgenden Elemente in $_SERVER vorfinden." ("kann" gedanklich unterstrichen).
Tschö, Auge
Hallöchen,
Davon abgesehen lässt sich dieser Pfad ja auch anders ermitteln (und wenn's die Nachfrage beim Hoster ist) und eine selbst angelegte Variable oder Konstante, die vor die Pfade zu den Includes geschnallt wird, ist ja auch kein Problem.
Genau das (selbst ermitteln und vor die Pfade zu den Includes schnallen) und nix anderes mach ich. Wobei die Schleife den in der Variablen gespeicherten Pfad an den Speicherort der aufrufenden Datei im Dateisystem anpasst.
MfG
vaudi
Hallo
Davon abgesehen lässt sich dieser Pfad ja auch anders ermitteln (und wenn's die Nachfrage beim Hoster ist) und eine selbst angelegte Variable oder Konstante, die vor die Pfade zu den Includes geschnallt wird, ist ja auch kein Problem.
Genau das (selbst ermitteln und vor die Pfade zu den Includes schnallen) und nix anderes mach ich. Wobei die Schleife den in der Variablen gespeicherten Pfad an den Speicherort der aufrufenden Datei im Dateisystem anpasst.
Und genau _das_ ist unnötig. Beispiel:
Der Pfad zu deinem Webspace sei /var/www/user/web12345/. Der Pfadteil ist für dich _immer_ gleich. Das Verzeichnis, in dem deine Webseite(n) liegen dürfen, sei "html" und da du mehrere Domains betreibst, liegen deren Ressourcen darunter in "domain1" und "domain2".
Eine Datei namens "index.php" im Wurzelverzeichnis von "domain1" würde immer unter /var/www/user/web12345/html/domain1/index.php zu finden sein. Eine Datei namens datei.name, die ich in "domain1" einbinde, die aber aus "domain2" stammt, kann ich immer über deren absoluten Pfad im Dateisystem finden, der da /var/www/user/web12345/html/domain2/datei.name lauten soll. Ich finde diese Datei mit exakt dieser Pfadangabe, egal, von welcher Verzeichnisebene innerhalb des Dateisystems ich sie auch aufrufe.
Kein Suchen nach oben oder unten, kein Anhängen von "../" oder was auch immer, nur ein im Dateisystem absoluter Pfad, der die Datei systemweit eindeutig identifiziert.
Tschö, Auge