Come includere file PHP che richiedono un percorso assoluto?


95

Ho una struttura di directory come la seguente;

script.php

inc / include1.php
inc / include2.php

oggetti / oggetto1.php
oggetti / oggetto2.php

soap / soap.php

Ora, uso quegli oggetti in entrambi script.phpe /soap/soap.php, potrei spostarli, ma voglio la struttura della directory in questo modo per un motivo specifico. Quando si esegue script.phpil percorso di inclusione è inc/include.phpe durante l'esecuzione di /soap/soap.phpesso è ../inc, il lavoro percorsi assoluti, /mnt/webdev/[project name]/inc/include1.php...ma è una soluzione di brutto se mai voglia di spostare la directory in una posizione diversa.

Quindi esiste un modo per utilizzare percorsi relativi o un modo per generare a livello di codice "/mnt/webdev/[project name]/"?

Risposte:


149

Questo dovrebbe funzionare

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

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

Modifica: aggiunto imporvement da aussieviking


2
Fai attenzione, funzionerà solo se esegui lo script tramite un server web che popolaDOCUMENT_ROOT
Phil

solo una domanda, perché realpath () per $ _SERVER ["DOCUMENT_ROOT"]? Questo non deve produrre sempre il percorso canonico?
João Pimentel Ferreira

44

Puoi usare percorsi relativi. Prova __FILE__. Questa è una costante PHP che restituisce sempre il percorso / nome del file dello script in cui si trova. Quindi, in soap.php, potresti fare:

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

Il percorso completo e il nome del file. Se utilizzato all'interno di un include, viene restituito il nome del file incluso. A partire da PHP 4.0.2, __FILE__contiene sempre un percorso assoluto con collegamenti simbolici risolti mentre nelle versioni precedenti conteneva un percorso relativo in alcune circostanze. (fonte)

Un'altra soluzione potrebbe essere quella di impostare un percorso di inclusione nel tuo file httpd.conf o .htaccess.


8
Penso che dovresti aggiungere un /all'inizio dell'espressione citata, per separare il nome ..dal FILE .
Dunaril

9
Nota che a partire da PHP 5.3.0 puoi usare la costante magica __DIR__invece di dover usare dirname(__FILE__). (Documenti PHP)
Erwin Wessels

3
include dirname(__FILE__).'/../inc/include.php';Non dimenticare la "/" prima del percorso relativo.
Steven Leimberg

6

Un altro modo per gestire questo problema che elimina qualsiasi necessità di include è utilizzare la funzione di caricamento automatico . Includere tutto ciò di cui il tuo script ha bisogno "Just in Case" può ostacolare le prestazioni. Se gli include sono tutte definizioni di classe o di interfaccia e si desidera caricarle solo quando necessario, è possibile sovraccaricare la __autoload()funzione con il proprio codice per trovare il file di classe appropriato e caricarlo solo quando viene chiamato. Ecco l'esempio dal manuale:

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

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

Finché imposti le tue variabili include_path di conseguenza, non avrai mai più bisogno di includere un file di classe.



5

È possibile definire una costante con il percorso della directory principale del progetto e quindi inserirla all'inizio del percorso.


2

Un'altra opzione, relativa a quella di Kevin, è use __FILE__, ma sostituisci invece il nome del file php al suo interno:

<?php

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

?>

Lo uso da un po '. L'unico problema è che a volte non hai $_SERVER['SCRIPT_NAME'], ma a volte c'è un'altra variabile simile.


2

Ho trovato che funzioni molto bene!

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

Uso:

<?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');

?>

1

Penso che il modo migliore sia mettere i tuoi include nel tuo percorso di inclusione PHP. Ci sono vari modi per farlo a seconda della configurazione.

Quindi puoi semplicemente fare riferimento a

require_once 'inc1.php';

dall'interno di qualsiasi file, indipendentemente da dove si trova, sia negli include che nei file accessibili dal Web o in qualsiasi livello di sottodirectory nidificate.

Ciò consente di avere i file di inclusione al di fuori della radice del server web, che è una best practice.

per esempio

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

Inoltre, controlla __autoload per il caricamento lento dei file di classe

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

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


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

Uso questa riga di codice. Torna all'inizio della struttura del sito, quindi torna al file desiderato.

Ad esempio, diciamo che ho questo albero di file:

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

Posso includere il file functions.php ovunque mi trovi, semplicemente copiandolo

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

Se è necessario utilizzare questo codice molte volte, è possibile creare una funzione che restituisca la str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))parte. Quindi inserisci questa funzione nel primo file che includi. Ho un file "initialize.php" che includo all'inizio di ogni pagina php e che contiene questa funzione. La prossima volta che dovrò includere file, in effetti userò solo la funzione (denominata path_back):

require(path_back()."/_resources/another_php_file.php");

0

@Flubba, questo mi permette di avere cartelle all'interno della mia directory include? flat include directory mi fanno venire gli incubi. poiché l'intera directory degli oggetti dovrebbe essere nella directory inc.

Sì, assolutamente. Quindi, ad esempio, utilizziamo un singolo livello di sottocartelle, generalmente:

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

Devi stare attento a fare affidamento sul percorso di inclusione troppo in siti ad alto traffico, perché php deve cercare attraverso la directory corrente e quindi tutte le directory sul percorso di inclusione per vedere se il tuo file è lì e questo può rallentare le cose vanno bene se vieni martellato.

Quindi, ad esempio, se stai facendo MVC, inserirai il percorso della directory dell'applicazione nel percorso di inclusione e quindi specifichi i riferimenti alle cose nel modulo

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

o qualsiasi altra cosa.

Ma in generale, ti consente solo di lavorare con percorsi molto brevi nel tuo PHP che funzioneranno da qualsiasi luogo ed è molto più facile da leggere di tutto quel malarkey di root del documento realpath.

Il vantaggio di quelle alternative basate su script che altri hanno suggerito è che funzionano ovunque, anche su scatole condivise; l'impostazione del percorso di inclusione richiede un po 'più di pensiero e impegno ma, come ho detto, ti consente di iniziare a utilizzare __autoload che è il più interessante.


0

Se intendi includere un percorso specifico nella maggior parte dei file nella tua applicazione, crea una variabile globale nella cartella principale.

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

Ora questa variabile globale " APPLICATION_PATH " può essere utilizzata per includere tutti i file invece di chiamare realpath () ogni volta che includi un nuovo file.

EX:

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

Spero che sia d'aiuto ;-)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.