Wenn ich Bilder referenziere, mache ich fast immer etwas wie das hier
<img src="/images/logo.png" alt="logo">
Das ist ein relativer Dateipfad, aber er beginnt im Root-Verzeichnis der Website. So referenziert er immer denselben Ort, egal in welchem Verzeichnis sich der Code-Schnipsel befindet. Wenn er nicht mit diesem „/“ beginnen würde, wäre es immer noch ein relativer Dateipfad, aber der Ort würde davon abhängen, in welchem Verzeichnis Sie sich gerade befinden. Es könnte gut funktionieren, wenn Sie sich unter /index.php befinden, aber wenn das zu /contact/ verschoben wird, bricht der Dateipfad, weil sich der *Bilder*-Ordner im Root befindet und nicht in /contact/.
Gesunder Menschenverstand.
Aber das wird bei einer serverseitigen Sprache wie PHP etwas komplizierter. Sie können auch Includes mit PHP wie folgt machen
<?php include("header.php"); ?>
Da es nicht mit „/“ beginnt, leidet es unter demselben Problem wie unser Bildbeispiel. Wenn der Include-Code in ein anderes Verzeichnis verschoben wird, kann die Referenz fehlschlagen. Aber bei PHP funktioniert das einfache Verwenden des beginnenden „/“ nicht, was sehr verwirrend sein kann.
Das Problem ist, dass PHP ein wenig „tiefer“ in das Dateisystem Ihres Servers schauen kann als HTML. Zum Beispiel befindet sich das öffentliche Webverzeichnis von CSS-Tricks auf meinem Server tatsächlich unter „/var/www/vhosts/css-tricks.com/httpdocs“. Wenn Sie also einen Include mit einem „/“ am Anfang machen, schaut es WEIT tiefer, als Sie es beabsichtigen. Sie möchten eigentlich, dass es in diesem öffentlichen Webverzeichnis nachschaut. In meinem Fall „httpdocs“.
Um diese Funktionalität zurückzugewinnen und relative Dateipfade zu haben, die sich nicht ändern, verwenden Sie dieses kleine PHP-Schmankerl
<?php
$path = $_SERVER['DOCUMENT_ROOT'];
$path .= "/common/header.php";
include_once($path);
?>
Grundlagen für alle Programmierer, aber dieser hatte mich ewig im Griff.
Eine weitere Technik
Brian Vanderberg schreibt
Ich habe festgestellt, dass in einigen Umgebungen
DOCUMENT_ROOTnicht richtig gesetzt zu sein scheint. Ich habe einen Weg entwickelt, der unabhängig vom Server ist und ob der Hosting-Anbieter die Möglichkeit bietet, einen Include- oder Auto-Prepend-Pfad festzulegen.Jedes Verzeichnis enthält eine
'meta'-Datei namens'__php__.php'(oder wie auch immer man sie nennen möchte). Für alle Dateien in diesem Verzeichnis werden sie einfach wie folgt eingebunden:<?php include('__php__.php'); ?>. Die Datei selbst bindet einfach die im übergeordneten Verzeichnis liegende ein, bis hin zum Stammverzeichnis der Website. Die Datei im Stammverzeichnis kann dann andere Dateien einbinden, eine einfache Möglichkeit, Dateien automatisch einzubinden, auch wenn ein Dienstanbieter dies nicht unterstützt, und auch eine Variable wie'SITE_ROOTDIR'definieren, die dann später verwendet werden kann. Wenn die Quelldateien in ein anderes Verzeichnis verschoben werden, binden sie immer noch die __php__.php-Datei in diesem Verzeichnis ein und erhalten die SITE_ROOTDIR-Konstante aus der oberen __php__.php-Datei.Ich mache auch etwas Ähnliches für eine einfache Navigationsleiste, bei der jedes Verzeichnis eine
__navbar__.php-Datei hat und jede Seite sie einfach an der richtigen Stelle einbindet und sie übergeordnete Navigationselemente einbinden und eigene Navigationselemente definieren kann.Ein Vorteil davon ist, dass ein Teil der Website in einem Unterverzeichnis unterteilt werden kann und trotzdem den Root dieses Teils erhält, auch wenn es nicht der eigentliche Dokumenten-Root ist. Ein Nachteil ist, dass es bei stark frequentierten Websites zu Verlangsamungen beim Einbinden kommen kann.
Noch eine weitere
<?php set_include_path( get_include_path() . PATH_SEPARATOR . $_SERVER['DOCUMENT_ROOT'] ); ?>
Das funktioniert auf Nicht-Apache-Servern wie IIS nicht, da $_SERVER[‘DOCUMENT_ROOT‘] nicht gesetzt ist.
Das habe ich schon immer so gemacht und ich bin froh zu sehen, dass ich es richtig gemacht habe!
VIELEN DANK!…
Ich habe mich schon eine Weile über dieses Problem beschwert und dachte, ich könnte WAMP nicht richtig konfigurieren.
Gott sei Dank kümmern Sie sich um PHP-Neulinge!!! :P
Aber (natürlich) habe ich eine Anfängerfrage
Dieser Schnipsel muss anstelle von
<?php include (header.php) ?>in jedem Teil, wo wir etwas zu includieren haben, richtig?Ich glaube, es ist so, aber nur zur Bestätigung…
Nochmal vielen Dank… liebe Ihre Posts und Screencasts….
Das muss es nicht, es ist nur ein bisschen intelligenter, es so zu tun
< ? php require_once $_SERVER[‘DOCUMENT_ROOT’] . ” /common/header.php ” ; ? >
Eine bessere Option wäre so etwas wie
$path = dirname(__FILE__) . DIRECTORY_SEPARATOR;Dies macht keine Annahmen darüber, dass Dateien sich im Dokumenten-Root befinden.
Heilige Scheiße!
Es funktioniert nicht in meiner WAMP-Installation. Gibt es noch etwas zu beachten, um dies zu implementieren?
Es ist wichtig zu bedenken, dass Ihr DOCUMENT_ROOT in den meisten Fällen funktionieren sollte, aber dass es möglicherweise kein gültiger Dateisystempfad ist. Oftmals, in Shared-Hosting-Umgebungen, gibt dirname(__FILE__) den tatsächlichen Dateisystempfad zum aktuellen PHP-Skript zurück, aber diese beiden Pfade können unterschiedlich sein. Dies ist besonders relevant, wenn die absolute URL einer Datei bestimmt wird.
Beachten Sie auch, dass Windows-Dateipfade den Backslash „\“ verwenden und *nix-basierte Systeme den Schrägstrich „/“.
Das ist VIEL besser
<?php
// index.php
$path = realpath(dirname(__FILE__)) . “/”;
include_once $path . “/common/header.php”;
?>
Viel Spaß! ;D
Mein Fehler: Es sollte MAMP statt WAMP heißen (ich bin gerade auf Mac), konnte aber meine Kommentare nicht bearbeiten.
Ich habe über den Backslash unter Windows gelesen, aber das ist im Moment nicht mein Fall.
Ich kann nicht herausfinden, was ich falsch mache.
Ehrlich gesagt habe ich das noch nie auf einem lokalen Rechner mit PHP ausprobiert/getestet. Es würde mich nicht überraschen, wenn es sich etwas anders verhält als ein normaler Server.
Hallo Chris und alle,
wirklich nützlicher Tipp.
Wir möchten eine effizientere Lösung mit einer Zeile PHP empfehlen
Fügen Sie einfach diese Codezeile einmal in eine Datei wie config.php ein und vergessen Sie die Pfade zu den Includes, verwenden Sie einfach
include_once("header.php");Vorteil dieser Technik ist, dass sie keine zusätzlichen Variablen durch die native PHP-Einstellung „include_path“ erzeugt. Diese Lösung schützt auch vor der Situation, in der die Variable $_SERVER[‘DOCUMENT_ROOT‘]; vom tatsächlichen Pfad Ihres Skripts abweicht.
Danke — habe das schon lange gesucht. Habe es heute Morgen an meinen Programmierer weitergegeben. Er wird im Handumdrehen ein treuer Fan sein.
Wow! Das kam GENAU rechtzeitig. Ich wollte gerade herausfinden, wie ich die PHP-Includes handhaben kann. Ihre Beiträge sind immer relevant für etwas, an dem ich gerade arbeite.
Es wäre einfacher, einfach so zu machen yoursite.com/images/sample.png
Schau dir diesen jQuery-Bildrotator an, Chris. Ich versuche, dich auf Twitter zu DM.
http://malsup.com/jquery/cycle/
Noch besser wäre es, wenn Sie Ihren Dokumenten-Root zur Include-Pfad-Liste hinzufügen würden, damit Sie den Pfad nicht erstellen müssen
dann können Sie einfach
und es wird zuerst in Ihrem Doc-Root nachschauen.
Noch besser wäre es jedoch, Ihre PHP-Dateien nicht im Dokumenten-Root zu platzieren, sondern sie stattdessen woanders zu platzieren, damit Sie header.php nicht direkt aus dem Web aufrufen können.
Das ist schlau… header.php ist wahrscheinlich völlig nutzlos, wenn es aus dem Web geladen wird, daher wäre es schlau, sie aus dem öffentlichen Verzeichnis fernzuhalten.
Sehr schön. Und machen Sie weiter so mit diesen einfachen Tipps und Tricks. Ich schätze sie!
PHP war für mich eine großartige Lernerfahrung, aber definitiv schwierig für einen Designer zu verstehen, oder zumindest für diesen Designer :) PHP Include ist aber genial, toller Tipp hier!
Ich benutze das hier
print("<?php include($_SERVER['DOCUMENT_ROOT']."/header.php"); ?>");
Ich denke, es macht dasselbe, oder zumindest etwas Ähnliches, und ist kompakter.
Heh… Ich arbeite seit etwa 6 Monaten mit PHP und bin nie auf diese Idee gekommen. Tolle Arbeit!
Ja, das habe ich auch schon früher gemacht (wie Jason), aber ich dachte, es wäre nicht richtig. Ich bin froh, es hier zu sehen.
Jetzt sehe ich, dass ich richtig lag.
PHP hat tatsächlich eine Konfigurationsvariable, die alle Pfade enthält, auf denen es nach einer Datei sucht, die Sie einzubinden versuchen: include_path
Daher könnten Sie mit ini_set() diese Variable zur Laufzeit einfach überschreiben oder besser gesagt etwas hinzufügen.
Ich habe das hier geschrieben
Moment mal, wenn man einen Schrägstrich am Anfang von „/images/logo.png“ setzt, sollte das zum Root gehen, ohne einen Haufen „../../etc“ zu verwenden? Habe ich etwas übersehen all die Jahre?
Wenn ich es auf meinem Remote-Host teste, funktioniert es, aber wenn ich das lokal mit der Standard-Apache-Installation unter OS X sowie mit einem MAMP-Dateipfad mache, funktioniert beides nicht. Wie entwickelt man lokal und lässt das funktionieren?
Korrekt.
Lokal zu arbeiten ist einfach seltsam… Ich habe keine gute Antwort für Sie. Ich vermeide es aus diesem Grund. Warum sich die Mühe machen, wenn es live alles durcheinander ist?
Danke für die Antwort, Chris.
Wenn das der Fall ist, was meinten Sie mit „Wenn ich Bilder referenziere, mache ich fast immer etwas wie das hier:“?
Danke für die Seite. Immer eine großartige Lektüre.
Ich habe einen Weg gefunden, eine einzige öffentlich einsehbare Datei (index.php) zu verwenden, die dann eine leicht modifizierte Version von Tills Quack-Methode des URL-Parsings verwendet, dann einfach ein Meta-Tag im Header meines HTML setzt, um alle meine relativen Links funktionsfähig zu halten, wie folgt
<base href="http://yoursite.com/" />
Das beseitigt die meisten Kopfschmerzen bei relativen URLs und ist auch ziemlich portabel. Nachdem ich es einmal implementiert hatte, konnte ich den Code für jedes neue Projekt problemlos portieren.
Ihre Methode scheint wahrscheinlich großartig für den Umgang mit mehreren Verzeichnissen zu sein, aber es scheint schwierig zu sein, sie zu warten, wenn Ihre Verzeichnisse geändert werden.
Gut, PHP hier zu sehen!
– Jason
Der von Chris gepostete Code funktioniert bei mir in MAMP. Sie können Ihre PHP-Fehlerprotokolle in MAMP überprüfen (in Terminal eingeben
tail -f /Applications/MAMP/logs/php_error.log
) um zu sehen, warum es nicht funktioniert. Es gibt auch keinen wirklichen Grund, die Pfadvariable im Code festzulegen, wenn Sie sie nur einmal verwenden. Das sollte genauso gut funktionieren
Ich könnte dich küssen für diesen Code-Schnipsel. Endlich etwas, das ich zum Laufen bringen kann, danke Kyle! :)
Also, wenn
<img src="/images/logo.png" alt="logo" /
vom Root startet, was macht das hier?
<img src="./images/logo.png" alt="logo" />
Das Stück
<img src="./images/logo.png" alt="logo" />würde im Grunde die Datei *logo.png* im Ordner *images* relativ zum Speicherort der Seite referenzieren.
Wenn Sie alle Ihre Bilder in z. B. *http://somedomain.com/images/* aufbewahren, aber Ihre Datei sich in *http://somedomain.com/docs/* befindet, wäre die URL, die es für *logo.png* verwenden würde, *http://somedomain.com/docs/images/logo.png*.
Schöner kleiner Tipp, Chris!
Hier sind meine 2 Cent; wenn Sie viele PHP-Includes relativ zum Dokumenten-Root machen müssen, kann der folgende Schnipsel ein paar Tastendrücke sparen
Jetzt wären *alle* vorgenommenen Includes relativ zum Dokumenten-Root. Sie können also einfach verwenden
Ahhhh, wusste nichts von „set_include_path“, das ist eindeutig der effizienteste Weg, wenn man mehrere Includes macht.
Hey Chris, ich liebe deine Arbeit. Nur eine Kleinigkeit – warum nicht einfach das hier stattdessen tun?
Scheint mir natürlicher.
Ich glaube, die Kommentar-Engine hat Ihr Codebeispiel verschluckt. Senden Sie es mir gerne per E-Mail an [email protected] und ich werde den Kommentar aktualisieren. Danke Matt!
Sie können auch require(‚filename.ext‘) verwenden, was die Ausführung aller Zeilen danach stoppt, wenn keine Datei gefunden wird.
define(‘APPLICATION_PATH’, realpath(‘../’));
$paths = array(APPLICATION_PATH, get_include_path());
set_include_path(implode(PATH_SEPARATOR, $paths));
function __autoload($className)
{
$filename = str_replace(‘\’, ‘/’, $className).’.php’;
require_once $filename;
}
binden Sie diese Datei einfach in Ihren Header ein, sie ruft automatisch alle Dateien ab und bindet sie in den Header ein