Làm thế nào để bao gồm các tệp PHP yêu cầu một đường dẫn tuyệt đối?


95

Tôi có một cấu trúc thư mục như sau;

script.php

inc / include1.php
inc / include2.php

đối tượng / object1.php
đối tượng / object2.php

xà phòng / soap.php

Bây giờ, tôi sử dụng các đối tượng đó trong cả hai script.php/soap/soap.php, tôi có thể di chuyển chúng, nhưng tôi muốn cấu trúc thư mục như vậy vì một lý do cụ thể. Khi thực thi script.phpđường dẫn bao gồm inc/include.phpvà khi thực thi /soap/soap.php../inc, các đường dẫn tuyệt đối hoạt động, /mnt/webdev/[project name]/inc/include1.php...Nhưng đó là một giải pháp xấu nếu tôi muốn di chuyển thư mục đến một vị trí khác.

Vậy có cách nào để sử dụng các đường dẫn tương đối hoặc một cách để tạo lập trình "/mnt/webdev/[project name]/"không?

Câu trả lời:


149

Điều này sẽ hoạt động

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

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

Chỉnh sửa: thêm động lực bởi aussieviking


2
Hãy cẩn thận, điều này sẽ chỉ hoạt động nếu bạn thực thi tập lệnh thông qua một máy chủ web phổ biếnDOCUMENT_ROOT
Phil

chỉ là một câu hỏi, tại sao realpath () cho $ _SERVER ["DOCUMENT_ROOT"]? Điều này sẽ không luôn xuất ra đường dẫn chuẩn?
João Pimentel Ferreira

44

Bạn có thể sử dụng các đường dẫn tương đối. Cố gắng __FILE__. Đây là một hằng số PHP luôn trả về đường dẫn / tên tệp của tập lệnh chứa nó. Vì vậy, trong soap.php, bạn có thể làm:

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

Đường dẫn đầy đủ và tên tệp của tệp. Nếu được sử dụng bên trong bao gồm, tên của tệp được bao gồm sẽ được trả về. Kể từ PHP 4.0.2, __FILE__luôn chứa một đường dẫn tuyệt đối với các liên kết tượng trưng được giải quyết trong khi trong các phiên bản cũ hơn, nó chứa đường dẫn tương đối trong một số trường hợp. (nguồn)

Một giải pháp khác là đặt đường dẫn bao gồm trong tệp httpd.conf hoặc tệp .htaccess của bạn.


8
Tôi nghĩ rằng bạn nên thêm một /vào đầu của biểu thức được trích dẫn, để tách biệt ..khỏi tên FILE .
Dunaril

9
Lưu ý rằng kể từ PHP 5.3.0, bạn có thể sử dụng hằng số ma thuật __DIR__thay vì phải sử dụng dirname(__FILE__). (Tài liệu PHP)
Erwin Wessels

3
include dirname(__FILE__).'/../inc/include.php';Đừng quên dấu "/" trước đường dẫn tương đối.
Steven Leimberg

6

Một cách khác để xử lý điều này mà loại bỏ bất kỳ nhu cầu nào về bao gồm là sử dụng tính năng tự động tải . Bao gồm mọi thứ mà tập lệnh của bạn cần "Chỉ trong trường hợp" có thể cản trở hiệu suất. Nếu bao gồm của bạn là tất cả các định nghĩa lớp hoặc giao diện và bạn chỉ muốn tải chúng khi cần, bạn có thể nạp chồng __autoload()hàm bằng mã của riêng mình để tìm tệp lớp thích hợp và chỉ tải nó khi nó được gọi. Đây là ví dụ từ sách hướng dẫn:

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

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

Miễn là bạn đặt các biến include_path của mình cho phù hợp, bạn sẽ không bao giờ phải đưa vào một tệp lớp nữa.



5

Bạn có thể xác định một hằng số với đường dẫn đến thư mục gốc của dự án, sau đó đặt nó ở đầu đường dẫn.


2

Một tùy chọn khác, liên quan đến Kevin's, là sử dụng __FILE__, nhưng thay vào đó hãy thay thế tên tệp php từ bên trong nó:

<?php

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

?>

Tôi đã sử dụng cái này trong một thời gian. Vấn đề duy nhất là đôi khi bạn không có $_SERVER['SCRIPT_NAME'], nhưng đôi khi có một biến khác tương tự.


2

Tôi thấy điều này hoạt động rất tốt!

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

Sử dụng:

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

Tôi nghĩ rằng cách tốt nhất là đặt bao gồm của bạn trong đường dẫn bao gồm PHP của bạn. Có nhiều cách khác nhau để thực hiện việc này tùy thuộc vào thiết lập của bạn.

Sau đó, bạn có thể chỉ cần tham khảo

require_once 'inc1.php';

từ bên trong bất kỳ tệp nào bất kể nó ở đâu cho dù trong tệp bao gồm của bạn hoặc trong tệp có thể truy cập web của bạn, hoặc bất kỳ cấp độ thư mục con lồng nhau nào.

Điều này cho phép bạn có các tệp bao gồm bên ngoài gốc máy chủ web, đây là một phương pháp hay nhất.

ví dụ

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

Ngoài ra, hãy kiểm tra __autoload để tải chậm các tệp lớp

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");

Tôi sử dụng dòng mã này. Nó quay trở lại "đầu" của cây trang web, sau đó chuyển đến tệp mong muốn.

Ví dụ: giả sử tôi có cây tệp này:

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

Tôi có thể bao gồm tệp functions.php từ mọi lúc mọi nơi, chỉ bằng cách sao chép dán

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

Nếu bạn cần sử dụng mã này nhiều lần, bạn có thể tạo một hàm trả về str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))một phần. Sau đó, chỉ cần chèn chức năng này vào tệp đầu tiên bạn đưa vào. Tôi có một tệp "initialize.php" mà tôi đưa vào ở đầu mỗi trang php và có chứa hàm này. Lần tiếp theo tôi phải bao gồm các tệp, trên thực tế, tôi chỉ sử dụng hàm (có tên path_back):

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

0

@Flubba, điều này có cho phép tôi có các thư mục bên trong thư mục bao gồm của mình không? phẳng bao gồm các thư mục cho tôi những cơn ác mộng. vì toàn bộ thư mục đối tượng phải nằm trong thư mục inc.

Ồ vâng, hoàn toàn. Vì vậy, ví dụ, chúng tôi sử dụng một lớp thư mục con, nói chung:

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

Bạn cần phải cẩn thận với việc dựa vào đường dẫn bao gồm quá nhiều trong các trang web có lưu lượng truy cập thực sự cao, vì php phải tìm kiếm qua thư mục hiện tại và sau đó là tất cả các thư mục trên đường dẫn bao gồm để xem liệu tệp của bạn có ở đó không và điều này có thể làm chậm mọi thứ lên nếu bạn đang bị búa bổ.

Vì vậy, ví dụ: nếu bạn đang làm MVC, bạn sẽ đặt đường dẫn đến Directoy ứng dụng của mình trong đường dẫn bao gồm và sau đó chỉ định tham chiếu đến những thứ trong biểu mẫu

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

hay bất cứ cái gì.

Nhưng nói chung, nó chỉ cho phép bạn làm việc với các đường dẫn thực sự ngắn trong PHP của bạn, có thể hoạt động từ mọi nơi và dễ đọc hơn rất nhiều so với tất cả các đường dẫn bất thường gốc tài liệu đường dẫn.

Lợi ích của những lựa chọn thay thế dựa trên tập lệnh mà những người khác đã đề xuất là chúng hoạt động ở mọi nơi, ngay cả trên các hộp chia sẻ; việc thiết lập đường dẫn bao gồm cần thêm một chút suy nghĩ và nỗ lực nhưng như tôi đã đề cập cho phép bạn bắt đầu sử dụng __autoload, đây là cách tuyệt vời nhất.


0

Nếu bạn định bao gồm đường dẫn cụ thể trong hầu hết các tệp trong ứng dụng của mình, hãy tạo một biến Toàn cầu cho thư mục gốc của bạn.

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

Giờ đây, biến Global này " APPLICATION_PATH " có thể được sử dụng để bao gồm tất cả các tệp thay vì gọi realpath () mỗi khi bạn đưa vào một tệp mới.

VÍ DỤ:

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

Hy vọng nó giúp ;-)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.