Jak dołączyć pliki PHP, które wymagają bezwzględnej ścieżki?

95

Mam strukturę katalogów podobną do poniższej;

script.php

inc / include1.php
inc / include2.php

obiekty / obiekt1.php
obiekty / obiekt2.php

soap / soap.php

Teraz używam tych obiektów w obu script.phpi /soap/soap.php, mógłbym je przenieść, ale chcę mieć taką strukturę katalogów z konkretnego powodu. Podczas wykonywania script.phpścieżki dołączania jest inc/include.phpi podczas wykonywania /soap/soap.phpjej ../inc, ścieżki bezwzględne działają, /mnt/webdev/[project name]/inc/include1.php...ale jest to brzydkie rozwiązanie, jeśli kiedykolwiek chcę przenieść katalog do innej lokalizacji.

Czy jest więc sposób na użycie ścieżek względnych lub sposób na programowe generowanie "/mnt/webdev/[project name]/"?

Xenph Yan
źródło

Odpowiedzi:

149

To powinno działać

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

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

Edycja: dodane ulepszenie przez aussieviking

Peter Coulton
źródło
2
Uważaj, to zadziała tylko wtedy, gdy wykonasz skrypt za pośrednictwem serwera internetowego, który się zapełniaDOCUMENT_ROOT
Phil
tylko pytanie, dlaczego realpath () dla $ _SERVER ["DOCUMENT_ROOT"]? To nie zawsze daje ścieżkę kanoniczną?
João Pimentel Ferreira
44

Możesz użyć ścieżek względnych. Spróbuj __FILE__. Jest to stała PHP, która zawsze zwraca ścieżkę / nazwę pliku skryptu, w którym się znajduje. Tak więc w programie soap.phpmożesz:

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

Pełna ścieżka i nazwa pliku. Jeśli jest używany wewnątrz dołączenia, zwracana jest nazwa dołączonego pliku. Od PHP 4.0.2 __FILE__zawsze zawiera ścieżkę bezwzględną z rozwiązanymi dowiązaniami symbolicznymi, podczas gdy w starszych wersjach w pewnych okolicznościach zawierała ścieżkę względną. (źródło)

Innym rozwiązaniem byłoby ustawienie ścieżki włączania w pliku httpd.conf lub .htaccess.

Kevin
źródło
8
Myślę, że należy dodać /na początku cytowanej wypowiedzi, aby oddzielić ..od FILE nazwy.
Dunaril
9
Zauważ, że od PHP 5.3.0 możesz używać magicznej stałej __DIR__zamiast używania dirname(__FILE__). (Dokumentacja PHP)
Erwin Wessels
3
include dirname(__FILE__).'/../inc/include.php';Nie zapomnij o znaku „/” przed ścieżką względną.
Steven Leimberg
6

Innym sposobem rozwiązania tego problemu, który całkowicie eliminuje potrzebę dołączania, jest użycie funkcji automatycznego ładowania . Uwzględnianie wszystkiego, czego potrzebuje twój skrypt, „na wszelki wypadek” może obniżyć wydajność. Jeśli dołączone są wszystkie definicje klas lub interfejsów i chcesz je załadować tylko w razie potrzeby, możesz przeciążać __autoload()funkcję własnym kodem, aby znaleźć odpowiedni plik klasy i załadować go tylko wtedy, gdy jest wywoływany. Oto przykład z instrukcji:

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

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

Dopóki odpowiednio ustawisz zmienne include_path, nigdy nie będziesz musiał ponownie dołączać pliku klasy.

Sam McAfee
źródło
5

Możesz zdefiniować stałą ze ścieżką do katalogu głównego projektu, a następnie umieścić ją na początku ścieżki.

Ryan Fox
źródło
2

Inną opcją, związaną z Kevinem, jest użycie __FILE__, ale zamiast tego zastąp nazwę pliku php z niego:

<?php

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

?>

Używam tego od jakiegoś czasu. Jedynym problemem jest to, że czasami nie masz $_SERVER['SCRIPT_NAME'], ale czasami jest inna podobna zmienna.

Darryl Hein
źródło
2

Okazało się, że to działa bardzo dobrze!

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

Posługiwać się:

<?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
źródło
1

Myślę, że najlepszym sposobem jest umieszczenie dołączeń w ścieżce dołączania PHP. W zależności od konfiguracji można to zrobić na różne sposoby.

Następnie możesz po prostu odnieść się do

require_once 'inc1.php';

z wnętrza dowolnego pliku, niezależnie od tego, gdzie się on znajduje, czy w dołączonych plikach, czy w plikach dostępnych w sieci, czy też na dowolnym poziomie zagnieżdżonych podkatalogów.

Pozwala to na umieszczanie plików dołączanych poza katalogiem głównym serwera WWW, co jest najlepszym rozwiązaniem.

na przykład

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

Sprawdź również __autoload pod kątem leniwego ładowania plików klas

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

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

Polsonby
źródło
1
require(str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))."/path/to/file.php");

Używam tej linii kodu. Wraca na „górę” drzewa serwisu, a następnie przechodzi do żądanego pliku.

Na przykład, powiedzmy, że mam to drzewo plików:

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

Mogę dołączyć plik functions.php z dowolnego miejsca, po prostu kopiując wklej

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

Jeśli chcesz użyć tego kodu wiele razy, możesz utworzyć funkcję, która zwraca str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))część. Następnie wstaw tę funkcję do pierwszego dołączanego pliku. Mam plik „initialize.php”, który umieszczam na samej górze każdej strony php i który zawiera tę funkcję. Następnym razem, gdy będę musiał dołączyć pliki, po prostu używam funkcji (o nazwie path_back):

require(path_back()."/_resources/another_php_file.php");
Machavity
źródło
0

@Flubba, czy to pozwala mi mieć foldery w moim katalogu include? mieszkanie obejmuje katalogi dają mi koszmary. ponieważ cały katalog obiektów powinien znajdować się w katalogu inc.

O tak, absolutnie. Na przykład używamy pojedynczej warstwy podfolderów, ogólnie:

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

Musisz uważać na zbyt duże poleganie na ścieżce dołączania w witrynach o naprawdę dużym ruchu, ponieważ php musi przeszukiwać bieżący katalog, a następnie wszystkie katalogi na ścieżce dołączania, aby zobaczyć, czy twój plik tam jest, a to może spowolnić sprawy, jeśli dostajesz młotek.

Na przykład, jeśli wykonujesz MVC, umieścisz ścieżkę do katalogu swojej aplikacji w ścieżce dołączania, a następnie określ odwołanie do rzeczy w formularzu

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

lub cokolwiek.

Ale ogólnie rzecz biorąc, po prostu pozwala ci pracować z naprawdę krótkimi ścieżkami w twoim PHP, które będą działać z dowolnego miejsca i jest o wiele łatwiejsze do odczytania niż cały ten malarkey root dokumentu realpath.

Zaletą tych alternatywnych skryptów, które inni sugerowali, jest to, że działają one wszędzie, nawet na współdzielonych skrzynkach; ustawienie ścieżki dołączania wymaga trochę więcej przemyślenia i wysiłku, ale jak wspomniałem, pozwala ci zacząć używać __autoload, które jest po prostu najfajniejsze.

Polsonby
źródło
0

Jeśli zamierzasz dołączyć określoną ścieżkę do większości plików w aplikacji, utwórz zmienną globalną do folderu głównego.

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

Teraz ta zmienna globalna „ APPLICATION_PATH ” może zostać użyta do włączenia wszystkich plików zamiast wywoływania funkcji realpath () za każdym razem, gdy dołączasz nowy plik.

DAWNY:

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

Mam nadzieję, że to pomoże ;-)

yuvraj
źródło