2008-08-07 44 views
82

Tôi có cấu trúc thư mục như sau;Cách bao gồm các tệp PHP yêu cầu đường dẫn tuyệt đối?

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 hiện script.php đường dẫn bao gồm là inc/include.php và khi thực hiện /soap/soap.php../inc, đường dẫn tuyệt đối hoạt động, /mnt/webdev/[project name]/inc/include1.php... Nhưng đó là 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ì vậy, có cách nào để sử dụng đường dẫn tương đối hay cách tạo ra "/mnt/webdev/[project name]/" theo cách lập trình?

Trả lời

138

này nên làm việc

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

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

Edit: thêm imporvement bởi aussieviking

+0

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áy chủ web điền vào 'DOCUMENT_ROOT' – Phil

+0

chỉ là một câu hỏi, tại sao realpath() cho $ _SERVER [" DOCUMENT_ROOT "]? Điều này sẽ không đầu ra luôn luôn đường dẫn kinh điển? –

6

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 của bạn, và sau đó đặt nó ở đầu đường dẫn.

40

Bạn có thể sử dụng đường dẫn tương đối. Hãy thử __FILE__. . Đây là một hằng số PHP mà luôn luôn trả về path/filename của kịch bản đó là trong 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 tin của tập tin . 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ả lại. Kể từ PHP 4.0.2, __FILE__ luôn luôn chứa đường dẫn tuyệt đối với các liên kết được giải quyết trong khi ở các phiên bản cũ hơn có chứa đường dẫn tương đối trong một số trường hợp. (source)

Một giải pháp khác sẽ được thiết lập một bao gồm đường dẫn trong httpd.conf của bạn hoặc một tập tin .htaccess.

+8

Tôi nghĩ bạn nên thêm một '/' vào đầu biểu thức được trích dẫn, để tách biệt '..' khỏi tên __FILE__. – Dunaril

+8

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)] (http://www.php.net/manual/en/language.constants.predefined.php) –

+3

'bao gồm dirname (__ FILE __). '/ ../inc/include.php';' Đừng quên "/" trước đường dẫn tương đối. –

1

Tôi nghĩ cách tốt nhất là đưa các nội dung của bạn vào đường dẫn PHP bao gồm. 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 chỉ đơn giản là có thể tham khảo

require_once 'inc1.php'; 

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

Điều này cho phép bạn bao gồm các tệp của bạn bên ngoài gốc máy chủ web, đây là 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 cho lười tải các tập tin lớp

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

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

0

@Flubba, điều này không cho phép tôi có thư mục bên trong của tôi bao gồm thư mục ? 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 duy nhất của các thư mục con, nói chung là:

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

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

Vì vậy, ví dụ nếu bạn đang làm MVC, bạn muốn đặt đường dẫn đến directoy ứng dụng của bạn trong con đường bao gồm và sau đó xác định xem điều dưới dạng

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

hoặc bất cứ điều gì. Tuy nhiên, 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, nó sẽ hoạt động ở mọi nơi và dễ đọc hơn nhiều so với malarkey gốc của tài liệu realpath đó.

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

3

Một tùy chọn khác, liên quan đến Trịnh Gia Dĩnh, là sử dụng __FILE__, nhưng thay vì thay thế các tên file 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 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ự.

4

Một cách khác để xử lý việc này sẽ loại bỏ bất kỳ nhu cầu bao gồm nào cả là sử dụng tính năng autoload. 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ể quá tải hàm __autoload() bằng mã của riêng bạn để tìm tệp lớp thích hợp và chỉ tải nó khi được gọi. Dưới đây là ví dụ từ hướng dẫn sử dụng:

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

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

Miễn là bạn đặt biến include_path cho phù hợp, bạn không bao giờ phải bao gồm tệp lớp nữa.

3

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

?> 
2
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 đó đi đến tập tin mong muốn.

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

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

tôi có thể bao gồm các tập tin functions.php từ bất cứ nơi nào tôi, chỉ bằng cách copy 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ề phần str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1)). Sau đó, chỉ cần chèn hàm này vào tệp đầu tiên bạn đưa vào. Tôi có một tập tin "initialize.php" mà tôi bao gồm ở đầu của mỗi trang php và có chứa chức năng này. Lần sau, tôi phải bao gồm các file, i trên thực tế chỉ cần sử dụng chức năng (tên path_back):

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

Một cách ngắn

include($_SERVER['DOCUMENT_ROOT']."/inc/include1.php"); 

'DOCUMENT_ROOT': Các thư mục gốc tài liệu theo đó tập lệnh hiện tại là thi hành, như được định nghĩa trong tệp cấu hình của máy chủ.

Các vấn đề liên quan