| | | | |
| |||||||
| Tutorials Hier findest Du Tutorials, welche nach und nach ein fertiges Script ergeben. Sehen, lernen & verstehen! |
|
| | LinkBack (6) | Themen-Optionen | Thema bewerten |
| | |||
| Erfahrener Benutzer Registriert seit: 21.05.2008
Beiträge: 9.937
![]() | Hallo, einiges kann schiefgehen, wenn man versucht relative Pfade beim include/require zu verwenden. Es ist dabei zu beachten, dass ein include ohne vollstaendige Pfadangabe: PHP-Code: Zitat:
Der PHP-Interpreter verwendet also den Ordner des Skriptes als Basis, mit dem er aufgerufen wird. Dabei ist es voellig egal, welche weiteren Skripte im Verlauf mit include/require eingebunden werden. Sich den Unterschied klar zu machen, ist wichtig. Auch kann dies etwas verwirrend sein und mag unlogisch erscheinen, z.B. bei folgendem Dateisystem-Szenario: Code: global.inc.php wwwroot/index.php classes/MyClass.class.php PHP-Code: PHP-Code: PHP-Code: Beziehen wir nun ein, dass dirname($_SERVER["SCRIPT_FILENAME"]) als Basispfad verwendet wird, macht das ganze Sinn, denn der PHP-Interpreter wurde mit "index.php" aufgerufen und verwendet nun dessen Ordner als Basis-Verzeichnis, und "wwwroot/" . "classes/MyClass.class.php" existiert nunmal nicht. Wie loesen wir also das Problem? Nun es gibt viele Loesungen, wobei ich persoenlich in letzter Zeit zur am Ende beschriebenen Loesung tendiere, alle Loesungen sind allerdings akzeptabel. Wenn man PHP allerdings beruflich verwendet, sollte man sich schon ueberlegen, ob nicht ein professionelleres Handling Sinn macht. 1.) Wenn man weiss, dass "global.inc.php" immer aus "wwwroot" aufgerufen wird, kann man dieses Vorwissen nutzen und einsetzen, in dem man "global.inc.php" einfach dahingehend manipuliert, dass man den relativen Pfad so anpasst, dass er aus "wwwroot" loslaufend, korrekt ist: global.inc.php: PHP-Code: 2.) Feste, absolute Pfade: Der Nachteil von relativen Pfaden ist ganz offensichtlich, dass man vom Basis-Pfad abhaengig ist. Umgehen kann man das, in dem man absolute Pfade verwendet: global.inc.php: PHP-Code: Dies wird uebrigens von Windows und Linux verstanden, obwohl der DIRECTORY_SEPARATOR von Windows der Backslash (\) ist. Der Nachteil ist aber offensichtlich, das Projekt muss wissen wo es sich befindet, die Pfade stehen fest und sie muessen bei einem Server-Umzug (und sei es nur von der Entwicklungs- in die Produktiv-Umgebung) muehsam angepasst werden. Search&Replace ist eine feine Sache, Komfort sieht aber anders aus. 3.) Dynamische, absolute Pfade: Man kann sich natuerlich auch absolute Pfade selber zusammen bauen, in dem man die magische Konstante __FILE__ und wieder die Funktion dirname() verwendet. __FILE__ ist laut Beschreibung des Manual lediglich dies: Zitat:
Ruft man nun dirname(__FILE__) auf, hat man sich so seinen eigenen absoluten Basispfad erstellt: global.inc.php PHP-Code: Diese Intelligenz kann man natuerlich in eine Pfad-Konfigurationsdatei (belassen wir sie der Einfachheit halber in "global.inc.php") auslagern: PHP-Code: Nun kann jede Datei, die "global.inc.php" einbindet, diese Konstante verwenden, egal aus welcher Pfad-Ebene sie aufgerufen wird, immer absolut und damit korrekt: wwwroot/news/index.php: PHP-Code: Aber auch diese Loesung hat den Nachteil, dass die Anwendung ihren relativen Ort zur "global.inc.php" kennen muss (und wenn dies jede Datei muss, ist die Struktur de-facto star) und die Verwendung einer Konstanten (und die Kenntnis ihres Namens) fuer jeden include/require Befehl benoetigt wird. Eine zwar kleine Abhaengigkeit, aber auch eine kleine Abhaengigkeit ist eine Abhaengigkeit, die man natuerlich vermeiden moechte. 4.) __autoload Wenn es nur darum geht PHP-Klassen einzubinden, kann man die Funktion __autoload() verwenden: http://us.php.net/__autoload Die funktioniert allerdings nur fuer Klassen, nicht fuer andere Inline-Skripte oder Funktionen. 5.) PHP-Einstellung "include_path": Der "include_path" wird viel zu selten verwendet, was eigentlich verwundert. Schlaegt ein include fehl, weil die Datei nicht gefunden wird, werden die im "php_flag" "include_path" aufgefuehrten und mit PATH_SEPARATOR getrennten Pfade als Basis zur include-Anweisung verwendet und nacheinander bis zum Erfolg oder endgueltigen Misserfolg ausprobiert. Was nach einem endgueltigen Misserfolg passiert, entscheiden die Konstrukte include/require selbst und ist hier nachzulesen: http://us3.php.net/include/ http://us3.php.net/require/ Der Pfad laesst sich durch die Datei "php.ini", Flag "include_path" entweder hart per Server-Einstellung setzen, oder aber nachtraeglich ueber ".htaccess" oder dynamisch mit set_include_path(). Auslesen ist ueber get_include_path() moeglich. Wie erwaehnt werden hier die Pfade als String aufgelistet und sind nur mit dem in der PHP-Konstanten PATH_SEPARATOR festgelegten Zeichen getrennt. Es ist ein abhaengig vom Betriebssystem festgelegtes Zeichen, dass in seinen Pfaden nicht vorkommen darf, in Linux ueblicherweise der Doppelpunkt (:), unter Windows das Semikolon (;). Eine Funktion add_include_path($strIncludePath) koennte also so aussehen: PHP-Code: Nun koennten wir statt unserer Pfad-Konstante PATH_CLASSES einfach alle wichtigen Verzeichnisse zu unserem "include_path" hinzufuegen. Wildes includen funktioniert dann natuerlich immer noch nicht, denn wir muessen ja vorher bereits eine Vorauswahl getroffen haben, welche Pfade "wuerdig" sind, als Basisverzeichnis in den "include_path" aufgenommen zu werden. Dies gewaehrleistet ein systematisches aber flexibles Schema (was include ich grundsaetzlich bzw. konkret) und bleibt bei den ueblichen Anwendungen auch meistens ueberschaubar: Klassen, Funktionen, externe Bibliotheken (PEAR, Zend, phpMailer, ..) oder Models/Views/Controllers. Externe Bibliotheken verlangen ohnehin dass sie in den "include_path" aufgenommen werden (und PEAR ist es unter XAMPP auch schon automatisch), wie sollten sie auch sonst ohne die Verwendung von absoluten Pfad-Konstrukten wissen, wo und wie sie ihre eigenen Unterbibliotheken nachladen koennen. Da die genannten externen Bibliotheken PEAR, Zend und phpMailer eigentlich nur Klassen-Sammlungen sind koennen wir die Bibliotheken auch nur bei Bedarf verfuegbar machen: PEAR.inc.php: PHP-Code: Code: PEAR.inc.php PEAR/PEAR.php PEAR/PEAR/.. .. Ein PHP-Code: Das ganze automatisieren bzw. auf ein Minimum an Anweisungen runterbrechen kann man nun mit dem PHP-Flag "auto_prepend_file". Eingestellt, wird das darueber angegebene Skript vor jeder Ausfuehrung eines PHP-Skriptes ausgefuehrt: wwwroot/.htaccess: Code: php_flag auto_prepend_file "C:/path/to/my/project/includes/prepend.inc.php" Nun wird, bevor ein Skript ueber den Webserver ausgefuehrt wird (denn nur auf den hat ".htaccess" Einfluss), die Datei "global.inc.php" im leider absolut angegebenen Verzeichnis ausgefuehrt. Wenn wir nicht sowieso schon eine Bootstrap-Datei verwenden, bei der dieses Verfahren (fast) unnuetz ist, haben wir es jetzt geschafft und koennen in "prepend.inc.php" unseren "include_path" setzen: prepend.inc.php: PHP-Code: Es ist anzuraten, dass in dieser Datei so wenig Intelligenz wie moeglich verwendet wird, nach Moeglichkeit sollte sie nur den "include_path" setzen, fertig. Denn auch das Debuggen in dieser Datei ist schwierig und da diese Datei vor jedem Skript ausgefuehrt wird, sollte es keinen irgendwie gearteten Bug produzieren. Bugs entstehen in komplexen Systemen, also versuchen wir dem mit Einfachheit entgegenzuwirken. Der Nachteil wurde bereits genannt: Wir muessen einmalig unseren absoluten Pfad fuer das Projekt kennen und ihn in der ".htaccess" Datei setzen. Das ist schlecht, laesst sich aber meines Wissens nicht vermeiden (wenn diese Information falsch ist, lasst es mich wissen). Einmalig heisst aber wirklich einmalig, pro Entwicklungsumgebung. Der Vorteil ist nun, dass unsere komplexe Anwendung nun rein garnichts ueber sich wissen muss, weder wie die Pfadkonstante heissen, ob es welche gibt und schon garnicht muss die Anwendung wissen, wo sich welche Dateien befinden. All dies uebernimmt nun PHP aus dem Wissen der fuer "include_path" gelieferten Pfade. Eine clevere __autoload Funktion erledigt den Rest: PHP-Code: Auch sie kennt nur die Details, die sie wissen muss. Alle Bibliotheken funktionieren nun in jeder Umgebung, in der "include_path" korrekt gesetzt ist, eine Voraussetzung die sich notfalls nachtraeglich schaffen laesst. Die "auto_prepend_file" Direktive laesst sich wie erwaehnt natuerlich bei der Verwendung von "Bootstrapping" vermeiden (womit man auch auf absolute Pfade vermeiden kann), allerdings kommt es in komplexen Anwendungen oft genug vor, dass man [mein Gott der Hund hier furzt wie ein Weltmeister] dann doch das ein oder andere Skript hat, das selbstaendig laeuft, seien es Bild-Generatoren oder Download-Manager, die man vielleicht von der komplexen Controller-Struktur entkoppeln moechte und dann faengt man wieder an, das Wissen ueber den Aufbau der Anwendung zu verteilen. Soviel dazu. | ||
| | |
| | |
| PHP Code Flüsterer Registriert seit: 21.08.2005 Beiträge: 4682 PHP-Kenntnisse: Fortgeschritten | |
|
| Themen-Optionen | |
| Thema bewerten | |
|
|
LinkBacks (?)
LinkBack to this Thread: http://www.php.de/tutorials/45917-php-falsche-pfade-bei-include-require-ohne-include_path.html | ||||
| Erstellt von | For | Type | Datum | |
| Les einfach den Text, es geht um PHP (include) | This thread | Refback | 06.08.2011 11:49 | |
| einseinself | Homepagehilfe | [PHP & MySQL] Include-Problem | This thread | Refback | 27.06.2011 09:25 | |
| einseinself | Homepagehilfe | [PHP & MySQL] Include-Problem | This thread | Refback | 26.06.2011 18:12 | |
| [PHP] Include eines PHP Scripts aus anderem Ordner | This thread | Refback | 06.04.2011 00:55 | |
| Metacrawler - Die Metasuchmaschine. | This thread | Refback | 27.08.2010 13:28 | |
| Google INTERIA.PL - szukaj: Pfad und dateiname korrekt | This thread | Refback | 10.02.2009 09:48 | |
Ähnliche Themen | ||||
| Thema | Autor | Forum | Antworten | Letzter Beitrag |
| welche pfade denn nun für welche funktion? | Promaetheus | PHP Tipps 2006 | 6 | 08.11.2006 21:33 |
| falsche Eingaben in URL abfangen...id an DB etc... | argon | PHP Tipps 2007 | 2 | 18.11.2005 10:15 |
| Besucher kamen über folgende Suchanfragen bei Google auf diese Seite |
| include_path, php pfad, php include pfad, php pfade, php include_path, php require path, php include path, pfade php, php require pfad, include_path php, php include_path setzen, php include pfadangabe, include php pfad, pfade in php, php include absoluter pfad, pfad php, php pfad setzen, php include pfade, php include path setzen, include pfad php |

Dieser Inhalt ist unter einer Creative Commons-Lizenz lizenziert.