Wie füge ich PHP-Dateien hinzu, die einen absoluten Pfad erfordern?

95

Ich habe eine Verzeichnisstruktur wie die folgende;

script.php

inc / include1.php
inc / include2.php

objectes / object1.php
Objekte / object2.php

soap / soap.php

Jetzt verwende ich diese Objekte in beiden script.phpund /soap/soap.phpich könnte sie verschieben, aber ich möchte die Verzeichnisstruktur aus einem bestimmten Grund so. Bei der Ausführung ist script.phpder Include-Pfad inc/include.phpund bei der Ausführung ist /soap/soap.phpes../inc , funktionieren absolute Pfade. /mnt/webdev/[project name]/inc/include1.php...Es ist jedoch eine hässliche Lösung, wenn ich das Verzeichnis jemals an einen anderen Speicherort verschieben möchte.

Gibt es also eine Möglichkeit, relative Pfade zu verwenden oder die programmgesteuert zu generieren "/mnt/webdev/[project name]/"?

Xenph Yan
quelle

Antworten:

149

Das sollte funktionieren

$root = realpath($_SERVER["DOCUMENT_ROOT"]);

include "$root/inc/include1.php";

Bearbeiten: Verbesserung durch Aussieviking hinzugefügt

Peter Coulton
quelle
2
Seien Sie vorsichtig, dies wird immer nur funktionieren, wenn Sie das Skript über einen Webserver ausführen, der gefüllt istDOCUMENT_ROOT
Phil
nur eine Frage, warum realpath () für $ _SERVER ["DOCUMENT_ROOT"]? Dies soll nicht immer den kanonischen Pfad ausgeben?
João Pimentel Ferreira
44

Sie können relative Pfade verwenden. Versuchen Sie es __FILE__. Dies ist eine PHP-Konstante, die immer den Pfad / Dateinamen des Skripts zurückgibt, in dem sie sich befindet. soap.phpSie können also Folgendes tun:

include dirname(__FILE__).'/../inc/include.php';

Der vollständige Pfad und Dateiname der Datei. Bei Verwendung in einem Include wird der Name der enthaltenen Datei zurückgegeben. Seit PHP 4.0.2 __FILE__enthält es immer einen absoluten Pfad mit aufgelösten Symlinks, während es in älteren Versionen unter bestimmten Umständen einen relativen Pfad enthielt. (Quelle)

Eine andere Lösung wäre, einen Include-Pfad in Ihrer httpd.conf oder einer .htaccess-Datei festzulegen.

Kevin
quelle
8
Ich denke, Sie sollten /am Anfang des zitierten Ausdrucks ein hinzufügen , um den Namen ..von der DATEI zu trennen .
Dunaril
9
Beachten Sie, dass Sie seit PHP 5.3.0 die magische Konstante verwenden können, __DIR__anstatt sie verwenden zu müssen dirname(__FILE__). (PHP docs)
Erwin Wessels
3
include dirname(__FILE__).'/../inc/include.php';Vergessen Sie nicht das "/" vor dem relativen Pfad.
Steven Leimberg
6

Eine andere Möglichkeit, dies zu handhaben, ohne dass Includes erforderlich sind, ist die Verwendung der Autoload- Funktion. Wenn Sie alles einschließen, was Ihr Skript benötigt, kann "Just in Case" die Leistung beeinträchtigen. Wenn Ihre Includes alle Klassen- oder Schnittstellendefinitionen sind und Sie sie nur bei Bedarf laden möchten, können Sie die __autoload()Funktion mit Ihrem eigenen Code überladen , um die entsprechende Klassendatei zu finden und sie nur beim Aufruf zu laden. Hier ist das Beispiel aus dem Handbuch:

function __autoload($class_name) {
    require_once $class_name . '.php';
}

$obj  = new MyClass1();
$obj2 = new MyClass2(); 

Solange Sie Ihre include_path-Variablen entsprechend festlegen, müssen Sie nie wieder eine Klassendatei einfügen.

Sam McAfee
quelle
5

Sie können eine Konstante mit dem Pfad zum Stammverzeichnis Ihres Projekts definieren und diese dann an den Anfang des Pfads setzen.

Ryan Fox
quelle
2

Eine andere Option, die sich auf Kevins bezieht, ist die Verwendung __FILE__, aber ersetzen Sie stattdessen den Namen der PHP-Datei darin:

<?php

$docRoot = str_replace($_SERVER['SCRIPT_NAME'], '', __FILE__);
require_once($docRoot . '/lib/include.php');

?>

Ich benutze das schon eine Weile. Das einzige Problem ist, dass Sie manchmal keine haben $_SERVER['SCRIPT_NAME'], aber manchmal gibt es eine andere ähnliche Variable.

Darryl Hein
quelle
2

Ich fand das sehr gut!

function findRoot() { 
    return(substr($_SERVER["SCRIPT_FILENAME"], 0, (stripos($_SERVER["SCRIPT_FILENAME"], $_SERVER["SCRIPT_NAME"])+1)));
}

Verwenden:

<?php

function findRoot() {
    return(substr($_SERVER["SCRIPT_FILENAME"], 0, (stripos($_SERVER["SCRIPT_FILENAME"], $_SERVER["SCRIPT_NAME"])+1)));
}

include(findRoot() . 'Post.php');
$posts = getPosts(findRoot() . 'posts_content');

include(findRoot() . 'includes/head.php');

for ($i=(sizeof($posts)-1); 0 <= $i; $i--) {
    $posts[$i]->displayArticle();
}

include(findRoot() . 'includes/footer.php');

?>
Thane Gill
quelle
1

Ich denke, der beste Weg ist, Ihre Includes in Ihren PHP-Include-Pfad aufzunehmen. Abhängig von Ihrem Setup gibt es verschiedene Möglichkeiten, dies zu tun.

Dann können Sie einfach darauf verweisen

require_once 'inc1.php';

aus jeder Datei heraus, unabhängig davon, wo sie sich in Ihren Includes oder in Ihren über das Internet zugänglichen Dateien oder auf einer beliebigen Ebene verschachtelter Unterverzeichnisse befindet.

Auf diese Weise können Sie Ihre Include-Dateien außerhalb des Webserver-Stammverzeichnisses haben. Dies ist eine bewährte Methode.

z.B

site directory
    html (web root)
        your web-accessible files
    includes
        your include files

Überprüfen Sie auch __autoload auf das verzögerte Laden von Klassendateien

http://www.google.com/search?q=setting+php+include+path

http://www.google.com/search?q=__autoload

Polsonby
quelle
1
require(str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))."/path/to/file.php");

Ich benutze diese Codezeile. Es geht zurück zum "Anfang" des Site-Baums und dann zur gewünschten Datei.

Nehmen wir zum Beispiel an, ich habe diesen Dateibaum:

domain.com/aaa/index.php
domain.com/bbb/ccc/ddd/index.php
domain.com/_resources/functions.php

Ich kann die Datei functions.php von jedem Ort aus einfügen, indem ich sie einfach einfüge

require(str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))."/_resources/functions.php");

Wenn Sie diesen Code mehrmals verwenden müssen, können Sie eine Funktion erstellen, die das str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))Teil zurückgibt . Fügen Sie diese Funktion dann einfach in die erste Datei ein, die Sie einschließen. Ich habe eine "initialize.php" -Datei, die ich ganz oben auf jeder PHP-Seite einfüge und die diese Funktion enthält. Wenn ich das nächste Mal Dateien einschließen muss, benutze ich tatsächlich nur die Funktion (benannt)path_back ):

require(path_back()."/_resources/another_php_file.php");
Machavity
quelle
0

@Flubba, erlaubt mir das, Ordner in meinem Include-Verzeichnis zu haben? Flat Include-Verzeichnisse geben mir Albträume. da sich das gesamte Objektverzeichnis im inc-Verzeichnis befinden sollte.

Oh ja, absolut. So verwenden wir beispielsweise im Allgemeinen eine einzelne Ebene von Unterordnern:

require_once('library/string.class.php')

Sie müssen vorsichtig sein, wenn Sie sich bei Websites mit sehr hohem Datenverkehr zu sehr auf den Include-Pfad verlassen, da PHP das aktuelle Verzeichnis und dann alle Verzeichnisse im Include-Pfad durchsuchen muss, um festzustellen, ob Ihre Datei vorhanden ist, und dies kann sich verlangsamen Dinge auf, wenn Sie gehämmert werden.

Wenn Sie beispielsweise MVC ausführen, geben Sie den Pfad zu Ihrer Anwendungsdirektion in den Include-Pfad ein und geben dann an, auf welche Elemente im Formular verwiesen wird

'model/user.class'
'controllers/front.php'

oder Wasauchimmer.

Aber im Allgemeinen können Sie damit nur mit wirklich kurzen Pfaden in Ihrem PHP arbeiten, die von überall aus funktionieren, und es ist viel einfacher zu lesen als all diese Realpath-Dokument-Root-Malarkey.

Der Vorteil dieser skriptbasierten Alternativen, die andere vorgeschlagen haben, besteht darin, dass sie überall funktionieren, auch auf gemeinsam genutzten Boxen. Das Festlegen des Include-Pfads erfordert etwas mehr Gedanken und Mühe, aber wie bereits erwähnt, können Sie __autoload verwenden, das einfach das coolste ist.

Polsonby
quelle
0

Wenn Sie in den meisten Dateien Ihrer Anwendung einen bestimmten Pfad einfügen möchten, erstellen Sie eine globale Variable in Ihrem Stammordner.

define("APPLICATION_PATH", realpath(dirname(__FILE__) . '/../app'));
or 
define("APPLICATION_PATH", realpath(DIR(__FILE__) . '/../app'));

Nun diese globale Variable " APPLICATION_PATH " verwendet werden, um alle Dateien einzuschließen, anstatt jedes Mal, wenn Sie eine neue Datei einfügen, realpath () aufzurufen.

EX:

include(APPLICATION_PATH ."/config/config.ini";

Ich hoffe es hilft ;-)

Yuvraj
quelle