Bagaimana cara menyertakan file PHP yang membutuhkan jalur absolut?

95

Saya memiliki struktur direktori seperti berikut;

script.php

inc / include1.php
inc / include2.php

objek / objek1.php
objek / objek2.php

sabun / sabun.php

Sekarang, saya menggunakan objek tersebut di keduanya script.phpdan /soap/soap.php, saya dapat memindahkannya, tetapi saya ingin struktur direktori seperti itu untuk alasan tertentu. Ketika menjalankan script.phppath include adalah inc/include.phpdan ketika menjalankan /soap/soap.phpitu ../inc, path absolut kerja, /mnt/webdev/[project name]/inc/include1.php...Tapi itu solusi yang jelek jika aku pernah ingin pindah direktori ke lokasi yang berbeda.

Jadi, apakah ada cara untuk menggunakan jalur relatif, atau cara untuk menghasilkan secara terprogram "/mnt/webdev/[project name]/"?

Xenph Yan
sumber

Jawaban:

149

Ini seharusnya berhasil

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

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

Edit: menambahkan peningkatan dengan aussieviking

Peter Coulton
sumber
2
Hati-hati, ini hanya akan berhasil jika Anda menjalankan skrip melalui server web yang mengisiDOCUMENT_ROOT
Phil
hanya sebuah pertanyaan, mengapa realpath () untuk $ _SERVER ["DOCUMENT_ROOT"]? Ini tidak akan selalu menghasilkan jalur kanonik?
João Pimentel Ferreira
44

Anda dapat menggunakan jalur relatif. Coba __FILE__. Ini adalah konstanta PHP yang selalu mengembalikan jalur / nama file dari skrip tempatnya berada. Jadi, di soap.php, Anda dapat melakukan:

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

Path lengkap dan nama file dari file tersebut. Jika digunakan di dalam sebuah penyertaan, nama dari file yang disertakan dikembalikan. Sejak PHP 4.0.2, __FILE__selalu berisi jalur absolut dengan symlink yang diselesaikan sedangkan di versi yang lebih lama itu berisi jalur relatif dalam beberapa keadaan. (sumber)

Solusi lain adalah menetapkan jalur penyertaan di httpd.conf atau file .htaccess Anda.

Kevin
sumber
8
Saya pikir Anda harus menambahkan a /di awal ekspresi yang dikutip, untuk memisahkan ..dari nama FILE .
Dunaril
9
Perhatikan bahwa sejak PHP 5.3.0 Anda dapat menggunakan konstanta ajaib __DIR__daripada harus menggunakan dirname(__FILE__). (PHP docs)
Erwin Wessels
3
include dirname(__FILE__).'/../inc/include.php';Jangan lupa "/" sebelum jalur relatif.
Steven Leimberg
6

Cara lain untuk menangani ini yang sama sekali menghilangkan kebutuhan akan penyertaan adalah dengan menggunakan fitur muat otomatis . Memasukkan semua yang dibutuhkan skrip Anda "Just in Case" dapat menghambat kinerja. Jika penyertaan Anda adalah semua definisi kelas atau antarmuka, dan Anda ingin memuatnya hanya saat diperlukan, Anda dapat membebani __autoload()fungsi dengan kode Anda sendiri untuk menemukan file kelas yang sesuai dan memuatnya hanya saat dipanggil. Berikut adalah contoh dari manual:

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

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

Selama Anda menyetel variabel include_path sesuai, Anda tidak perlu menyertakan file kelas lagi.

Sam McAfee
sumber
5

Anda dapat menentukan sebuah konstanta dengan jalur ke direktori root proyek Anda, dan kemudian meletakkannya di awal jalur.

Ryan Fox
sumber
2

Opsi lain, terkait dengan Kevin, adalah menggunakan __FILE__, tetapi mengganti nama file php dari dalamnya:

<?php

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

?>

Saya telah menggunakan ini untuk sementara waktu. Satu-satunya masalah adalah terkadang Anda tidak punya $_SERVER['SCRIPT_NAME'], tetapi terkadang ada variabel lain yang serupa.

Darryl Hein
sumber
2

Saya menemukan ini bekerja dengan sangat baik!

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

Menggunakan:

<?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
sumber
1

Saya pikir cara terbaik adalah memasukkan include Anda ke dalam jalur include PHP Anda. Ada berbagai cara untuk melakukan ini tergantung pada penyiapan Anda.

Kemudian Anda bisa langsung merujuk ke

require_once 'inc1.php';

dari dalam file apa pun di mana pun itu berada, baik dalam penyertaan atau di file yang dapat diakses web Anda, atau tingkat subdirektori bertingkat apa pun.

Ini memungkinkan Anda untuk memiliki file yang disertakan di luar root server web, yang merupakan praktik terbaik.

misalnya

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

Selain itu, periksa __autoload untuk mengetahui pemuatan lambat file kelas

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

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

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

Saya menggunakan baris kode ini. Ini kembali ke "atas" dari pohon situs, lalu pergi ke file yang diinginkan.

Misalnya, saya memiliki pohon file ini:

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

Saya dapat menyertakan file functions.php dari manapun saya berada, hanya dengan menyalin paste

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

Jika Anda perlu menggunakan kode ini berkali-kali, Anda dapat membuat fungsi yang mengembalikan str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))bagian tersebut. Kemudian masukkan saja fungsi ini di file pertama yang Anda sertakan. Saya memiliki file "initialize.php" yang saya sertakan di bagian paling atas setiap halaman php dan yang berisi fungsi ini. Lain kali saya harus menyertakan file, saya sebenarnya hanya menggunakan fungsi (bernama path_back):

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

@Flubba, apakah ini mengizinkan saya untuk memiliki folder di dalam direktori include saya? datar termasuk direktori memberi saya mimpi buruk. karena seluruh direktori objek harus berada di direktori inc.

Oh ya, tentu saja. Jadi misalnya, kami menggunakan satu lapisan subfolder, umumnya:

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

Anda harus berhati-hati dengan terlalu mengandalkan jalur penyertaan di situs dengan lalu lintas sangat tinggi, karena php harus mencari melalui direktori saat ini dan kemudian semua direktori di jalur penyertaan untuk melihat apakah file Anda ada di sana dan ini dapat memperlambat segalanya jika Anda merasa terpukul.

Jadi misalnya jika Anda melakukan MVC, Anda akan meletakkan path ke application directoy Anda di path include dan kemudian tentukan refer to things di formulir.

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

atau terserah.

Tetapi secara umum, ini hanya memungkinkan Anda bekerja dengan jalur yang sangat pendek di PHP Anda yang akan berfungsi dari mana saja dan jauh lebih mudah dibaca daripada semua dokumen root malarkey realpath itu.

Manfaat dari alternatif berbasis skrip yang disarankan orang lain adalah mereka bekerja di mana saja, bahkan di kotak bersama; mengatur jalur penyertaan membutuhkan sedikit lebih banyak pemikiran dan usaha tetapi seperti yang saya sebutkan memungkinkan Anda mulai menggunakan __autoload yang paling keren.

Polsonby
sumber
0

Jika Anda akan menyertakan jalur tertentu di sebagian besar file dalam aplikasi Anda, buat variabel Global ke folder root Anda.

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

Sekarang variabel Global " APPLICATION_PATH " ini dapat digunakan untuk menyertakan semua file daripada memanggil realpath () setiap kali Anda menyertakan file baru.

EX:

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

Semoga membantu ;-)

yuvraj
sumber