2011-12-02 94 views
12

Nếu tôi sử dụng đường dẫn tuyệt đối, tôi không thể di chuyển toàn bộ thư mục sang vị trí mới. Nếu tôi sử dụng đường dẫn tương đối, tôi không thể di chuyển các tệp riêng lẻ sang các vị trí mới.Đường dẫn tuyệt đối và tương đối

Giải pháp ở đây là gì? Bạn có thiết lập một tệp cấu hình chứa đường dẫn gốc và đi từ đó không? Hoặc bạn có một quy tắc như: Không bao giờ di chuyển các tệp xung quanh?

Tôi đã thấy trong một số dự án mà mọi người sử dụng tên dirname (FILE). Điều gì là điểm của điều đó, tôi có nghĩa là, tại sao không chỉ đơn giản là để nó ra kể từ khi dirname là tương đối anyway (tùy thuộc vào nơi tập tin ngồi)?

+0

Việc sử dụng của 'dirname (__FILE __) 'hoặc' __DIR__' là ngay cả khi tệp được bao gồm nó sẽ vẫn trả về thư mục của tập lệnh hiện tại. Nếu bạn có một tệp bao gồm dir/script.php, đường dẫn include mặc định trong script.php sẽ là root và không phải là dir /. – Kokos

+1

@Frank Vilea: * Bạn có thiết lập một tập tin cấu hình chứa đường dẫn gốc và đi từ đó không? * ** yes ** –

+0

Tôi khá tệ ở đây, nhưng tôi đoán ý tưởng là trộn hai thứ đó lên. Bu thêm đường dẫn tuyệt đối vào tập lệnh chính và đường dẫn tương đối vào tệp được bao gồm và được sử dụng trong tập lệnh. tất nhiên, bạn không bao giờ có thể di chuyển bất kỳ tệp nào bằng cách sử dụng đường dẫn tương đối mà không thay đổi thứ gì đó trong khai báo đường dẫn tương đối. – OptimusCrime

Trả lời

14

bạn nên sử dụng một tập tin cấu hình mà sẽ được bao gồm trong mỗi dòng file đầu tiên, ví dụ ứng dụng của bạn trông giống như

gốc này/App/Plugins

bên trong thư mục gốc của bạn: app-config.php

if (!defined('ABSPATH')) 
    define('ABSPATH', dirname(__FILE__) . '/'); 

bây giờ, giả sử bạn phải bao gồm tệp plugin, vì vậy

bên trong thư mục Plugin: my-plugin.php

require_once '../../app-config.php'; 

bây giờ mọi thứ bên dưới dòng này có thể sử dụng ABSPATH

dụ bạn muốn tải một hình ảnh

<img src='".ABSPATH."Public/images/demo.png' alt=''/> 

bây giờ, điều này là đơn giản hơn nếu ứng dụng của bạn được thiết kế để tự động tải một số các tệp như

plugin-widget-1.php 

để mọi thứ bên trong tệp này hoặc bất kỳ tệp nào khác tệp được tải bởi tệp my-plugin.php có thể sử dụng ABSPATH mà không bao gồm mỗi lần tệp app-config.php.

với điều này trong tâm trí bạn có thể có tất cả các ngắn tay bạn muốn vào ví dụ app-config.php

define('UPLOAD_PATH', ABSPATH. 'Public/uploads/'); 
define('IMAGES_PATH', ABSPATH. 'Public/images/'); 
define('HELPERS_PATH', ABSPATH. 'App/helpers/'); 
... 

như vậy, bây giờ mà bạn có tất cả được xác định, nếu bạn cần phải di chuyển một tập tin, chúng ta hãy nói một thư mục mong dụ:

root/App/Plugins/Utils

chỉ inlucde require_once '../../../app-config.php';

rõ ràng là tôi giả tha t bạn không thay đổi đường dẫn mỗi lần =) anyway nếu bạn cần phải làm như vậy là luôn luôn đơn giản hơn để thay đổi một tập tin bao gồm thay vì hàng trăm.

niềm hy vọng này có ý nghĩa với bạn =)

+0

Tôi đang triển khai giải pháp này ngay bây giờ. Cảm ơn. –

1

Phụ thuộc vào cách sử dụng của bạn, xác định một hằng số để giữ con đường ứng dụng là một trong những thực tế phổ biến

Không sử dụng biến vì nó có thể bị ghi đè lên đâu đó trong ứng dụng của bạn và có thể phá vỡ ứng dụng của bạn

Is thậm chí tốt hơn để kết hợp với liên kết tượng trưng (biểu tượng để tạo ra các chi nhánh)

application dirs 
=============================== 
/home/latest   -> symlink 
/home/testing  -> symlink 
/home/20111202000000 -> latest development version 
/home/20111201000000 -> yesterday stable release 

Vì vậy, bạn có thể liên kết tượng trưng
/home/thử nghiệm ->/home/20111202000000 trong khi vẫn giữ ver ổn định sion,
/home/mới nhất ->/home/20111201000000

Với điều này, bạn không cần phải có nguy cơ phá vỡ điểm sản xuất của bạn trong khi làm một số thử nghiệm/phát triển, và bạn có thể dễ dàng thay đổi thư mục phát triển của bạn

+0

Tôi thực sự thực sự thích giải pháp này. Không bao giờ nghĩ đến việc sử dụng các liên kết tượng trưng. –

2

Tôi đã thấy trong một số dự án mà mọi người sử dụng tên dirname (FILE). Điều gì là điểm của điều đó, tôi có nghĩa là, tại sao không chỉ đơn giản là để nó ra kể từ khi dirname là tương đối anyway (tùy thuộc vào nơi tập tin ngồi)?

Nó liên quan đến đường dẫn bao gồm. dirname(__FILE__) (hoặc chỉ __DIR__ trong PHP> = 5.3) có sẵn để bạn có thể chạy tệp từ mọi vị trí. Trong trường hợp bạn đang sử dụng đường dẫn tương đối, giá trị "." có thể thay đổi. Xem:

berry @ berry-pc: ~% mèo so.php

<?php 
var_dump(realpath('.')); 
var_dump(realpath(__DIR__)); 

berry @ berry-pc: ~% php so.php

string(11) "/home/berry" 
string(11) "/home/berry" 

berry @ berry-pc: ~% cd foo

berry @ berry-pc: ~/foo% php .. /so.php

string(15) "/home/berry/foo" 
string(11) "/home/berry" 

Vì vậy, nó là tương đối, nhưng nó tương đối so với thư mục làm việc hiện tại, chứ không phải vào thư mục tập tin được đặt ở đó. Đó là lý do tại sao bạn sẽ muốn sử dụng __DIR__ cho việc này. Và nhân tiện; vâng, tôi không di chuyển các tập tin xung quanh một lô khủng khiếp. Nếu tôi làm như vậy, tôi sẽ phải cập nhật mọi cuộc gọi đến tệp đó, mặc dù tôi không yêu cầu hoặc bao gồm nhiều khủng khiếp nữa, vì tôi đang sử dụng một số Autoloader.

Đối với các tệp khác mà tôi đang đề cập đến (chẳng hạn như tệp mẫu), tôi đặt đường dẫn theo cách thủ công, nhưng sau khi. Sau đó, tôi tham khảo $path . '/filename.php';, vì vậy sẽ dễ dàng thay đổi sau này.

+2

Cảm ơn bài đăng rất chi tiết này. Bây giờ nó có ý nghĩa. Ngoài ra tính năng tự động tải có vẻ rất gọn gàng. –

+0

@FrankVilea Được chào đón nhiều nhất. –

0

Đường dẫn tuyệt đối tốt hơn từ góc độ hiệu suất khi sử dụng bộ nhớ cache opcode hoặc nhiều câu lệnh yêu cầu/bao gồm (mặc dù nó chỉ đáng chú ý khi bạn bắt đầu bao gồm hàng trăm tệp, có thể xảy ra khi sử dụng khung như Zend/Symfony/etc).

Với đường dẫn tương đối, bộ nhớ cache opcode và php phải làm việc trên đường dẫn tệp mỗi lần trước khi nó có thể hoạt động nếu nó đã biết về tệp và nếu nó cần tải lại. PHP nội bộ duy trì một hashmap của các tập tin để tập tin địa điểm đó là rất nhanh chóng miễn là nó không phải làm việc tính toán trên mỗi lần.

0

tôi luôn luôn sử dụng đường dẫn tuyệt đối, nhưng tôi cũng bắt đầu bất kỳ dự án tùy chỉnh PHP với một file bootstrap nơi tôi xác định các đường dẫn thường được sử dụng nhất là hằng số, dựa trên giá trị chiết xuất từ $_SERVER.

Đây là cách tôi xác định các đường gốc của tôi:

define("LOCAL_PATH_ROOT", $_SERVER["DOCUMENT_ROOT"]); 
define("HTTP_PATH_ROOT", isset($_SERVER["HTTP_HOST"]) ? $_SERVER["HTTP_HOST"] : (isset($_SERVER["SERVER_NAME"]) ? $_SERVER["SERVER_NAME"] : '_UNKNOWN_')); 

Đường dẫn LOCAL_PATH_ROOT là tài liệu gốc. Đường dẫn HTTP_PATH_ROOT tương đương khi truy cập cùng một đường dẫn qua HTTP.

Vào thời điểm đó, chuyển đổi bất kỳ con đường địa phương để một con đường HTTP có thể được thực hiện với đoạn mã sau:

str_replace(LOCAL_PATH_ROOT, RELATIVE_PATH_ROOT, $my_path) 

Nếu bạn muốn đảm bảo khả năng tương thích với các máy chủ dựa trên Windows, bạn sẽ cần phải thay thế các thư mục seperator với một seperator URL cũng như:

str_replace(LOCAL_PATH_ROOT, RELATIVE_PATH_ROOT, str_replace(DIRECTORY_SEPARATOR, '/', $my_path)) 

Dưới đây là mã bootstrap đầy đủ mà tôi đang sử dụng cho PHP PowerTools boilerplate:

defined('LOCAL_PATH_BOOTSTRAP') || define("LOCAL_PATH_BOOTSTRAP", __DIR__); 

// ----------------------------------------------------------------------- 
// DEFINE SEPERATOR ALIASES 
// ----------------------------------------------------------------------- 
define("URL_SEPARATOR", '/'); 
define("DS", DIRECTORY_SEPARATOR); 
define("PS", PATH_SEPARATOR); 
define("US", URL_SEPARATOR); 

// ----------------------------------------------------------------------- 
// DEFINE ROOT PATHS 
// ----------------------------------------------------------------------- 
define("RELATIVE_PATH_ROOT", ''); 
define("LOCAL_PATH_ROOT", $_SERVER["DOCUMENT_ROOT"]); 
define("HTTP_PATH_ROOT", 
     isset($_SERVER["HTTP_HOST"]) ? 
     $_SERVER["HTTP_HOST"] : (
     isset($_SERVER["SERVER_NAME"]) ? 
     $_SERVER["SERVER_NAME"] : '_UNKNOWN_')); 

// ----------------------------------------------------------------------- 
// DEFINE RELATIVE PATHS 
// ----------------------------------------------------------------------- 
define("RELATIVE_PATH_BASE", 
     str_replace(LOCAL_PATH_ROOT, RELATIVE_PATH_ROOT, getcwd())); 
define("RELATIVE_PATH_APP", dirname(RELATIVE_PATH_BASE)); 
define("RELATIVE_PATH_LIBRARY", RELATIVE_PATH_APP . DS . 'vendor'); 
define("RELATIVE_PATH_HELPERS", RELATIVE_PATH_BASE); 
define("RELATIVE_PATH_TEMPLATE", RELATIVE_PATH_BASE . DS . 'templates'); 
define("RELATIVE_PATH_CONFIG", RELATIVE_PATH_BASE . DS . 'config'); 
define("RELATIVE_PATH_PAGES", RELATIVE_PATH_BASE . DS . 'pages'); 
define("RELATIVE_PATH_ASSET", RELATIVE_PATH_BASE . DS . 'assets'); 
define("RELATIVE_PATH_ASSET_IMG", RELATIVE_PATH_ASSET . DS . 'img'); 
define("RELATIVE_PATH_ASSET_CSS", RELATIVE_PATH_ASSET . DS . 'css'); 
define("RELATIVE_PATH_ASSET_JS", RELATIVE_PATH_ASSET . DS . 'js'); 

// ----------------------------------------------------------------------- 
// DEFINE LOCAL PATHS 
// ----------------------------------------------------------------------- 
define("LOCAL_PATH_BASE", LOCAL_PATH_ROOT . RELATIVE_PATH_BASE); 
define("LOCAL_PATH_APP", LOCAL_PATH_ROOT . RELATIVE_PATH_APP); 
define("LOCAL_PATH_LIBRARY", LOCAL_PATH_ROOT . RELATIVE_PATH_LIBRARY); 
define("LOCAL_PATH_HELPERS", LOCAL_PATH_ROOT . RELATIVE_PATH_HELPERS); 
define("LOCAL_PATH_TEMPLATE", LOCAL_PATH_ROOT . RELATIVE_PATH_TEMPLATE); 
define("LOCAL_PATH_CONFIG", LOCAL_PATH_ROOT . RELATIVE_PATH_CONFIG); 
define("LOCAL_PATH_PAGES", LOCAL_PATH_ROOT . RELATIVE_PATH_PAGES); 
define("LOCAL_PATH_ASSET", LOCAL_PATH_ROOT . RELATIVE_PATH_ASSET); 
define("LOCAL_PATH_ASSET_IMG", LOCAL_PATH_ROOT . RELATIVE_PATH_ASSET_IMG); 
define("LOCAL_PATH_ASSET_CSS", LOCAL_PATH_ROOT . RELATIVE_PATH_ASSET_CSS); 
define("LOCAL_PATH_ASSET_JS", LOCAL_PATH_ROOT . RELATIVE_PATH_ASSET_JS); 

// ----------------------------------------------------------------------- 
// DEFINE URL PATHS 
// ----------------------------------------------------------------------- 
if (US === DS) { // needed for compatibility with windows 
    define("HTTP_PATH_BASE", HTTP_PATH_ROOT . RELATIVE_PATH_BASE); 
    define("HTTP_PATH_APP", HTTP_PATH_ROOT . RELATIVE_PATH_APP); 
    define("HTTP_PATH_LIBRARY", false); 
    define("HTTP_PATH_HELPERS", false); 
    define("HTTP_PATH_TEMPLATE", false); 
    define("HTTP_PATH_CONFIG", false); 
    define("HTTP_PATH_PAGES", false); 
    define("HTTP_PATH_ASSET", HTTP_PATH_ROOT . RELATIVE_PATH_ASSET); 
    define("HTTP_PATH_ASSET_IMG", HTTP_PATH_ROOT . RELATIVE_PATH_ASSET_IMG); 
    define("HTTP_PATH_ASSET_CSS", HTTP_PATH_ROOT . RELATIVE_PATH_ASSET_CSS); 
    define("HTTP_PATH_ASSET_JS", HTTP_PATH_ROOT . RELATIVE_PATH_ASSET_JS); 
} else { 
    define("HTTP_PATH_BASE", HTTP_PATH_ROOT . 
      str_replace(DS, US, RELATIVE_PATH_BASE)); 
    define("HTTP_PATH_APP", HTTP_PATH_ROOT . 
      str_replace(DS, US, RELATIVE_PATH_APP)); 
    define("HTTP_PATH_LIBRARY", false); 
    define("HTTP_PATH_HELPERS", false); 
    define("HTTP_PATH_TEMPLATE", false); 
    define("HTTP_PATH_CONFIG", false); 
    define("HTTP_PATH_PAGES", false); 
    define("HTTP_PATH_ASSET", HTTP_PATH_ROOT . 
      str_replace(DS, US, RELATIVE_PATH_ASSET)); 
    define("HTTP_PATH_ASSET_IMG", HTTP_PATH_ROOT . 
      str_replace(DS, US, RELATIVE_PATH_ASSET_IMG)); 
    define("HTTP_PATH_ASSET_CSS", HTTP_PATH_ROOT . 
      str_replace(DS, US, RELATIVE_PATH_ASSET_CSS)); 
    define("HTTP_PATH_ASSET_JS", HTTP_PATH_ROOT . 
      str_replace(DS, US, RELATIVE_PATH_ASSET_JS)); 
} 

// ----------------------------------------------------------------------- 
// DEFINE REQUEST PARAMETERS 
// ----------------------------------------------------------------------- 
define("REQUEST_QUERY", 
     isset($_SERVER["QUERY_STRING"]) && $_SERVER["QUERY_STRING"] != '' ? 
     $_SERVER["QUERY_STRING"] : false); 
define("REQUEST_METHOD", 
     isset($_SERVER["REQUEST_METHOD"]) ? 
     strtoupper($_SERVER["REQUEST_METHOD"]) : false); 
define("REQUEST_STATUS", 
     isset($_SERVER["REDIRECT_STATUS"]) ? 
     $_SERVER["REDIRECT_STATUS"] : false); 
define("REQUEST_PROTOCOL", 
     isset($_SERVER["HTTP_ORIGIN"]) ? 
     substr($_SERVER["HTTP_ORIGIN"], 0, 
     strpos($_SERVER["HTTP_ORIGIN"], '://') + 3) : 'http://'); 
define("REQUEST_PATH", 
     isset($_SERVER["REQUEST_URI"]) ? 
     str_replace(RELATIVE_PATH_BASE, '', 
     $_SERVER["REQUEST_URI"]) : '_UNKNOWN_'); 
define("REQUEST_PATH_STRIP_QUERY", 
     REQUEST_QUERY ? 
     str_replace('?' . REQUEST_QUERY, '', REQUEST_PATH) : REQUEST_PATH); 

// ----------------------------------------------------------------------- 
// DEFINE SITE PARAMETERS 
// ----------------------------------------------------------------------- 
define("PRODUCTION", false); 
define("PAGE_PATH_DEFAULT", US . 'index'); 
define("PAGE_PATH", 
     (REQUEST_PATH_STRIP_QUERY === US) ? 
     PAGE_PATH_DEFAULT : REQUEST_PATH_STRIP_QUERY); 

Nếu bạn thêm mã ở trên để dự án của riêng bạn, xuất ra tất cả các hằng số sử dụng vào thời điểm này (mà có thể làm với get_defined_constants(true) nên đưa ra một kết quả trông hơi như thế này:

array (
    'LOCAL_PATH_BOOTSTRAP' => '/var/www/libraries/backend/Data/examples', 
    'URL_SEPARATOR' => '/', 
    'DS' => '/', 
    'PS' => ':', 
    'US' => '/', 
    'RELATIVE_PATH_ROOT' => '', 
    'LOCAL_PATH_ROOT' => '/var/www', 
    'HTTP_PATH_ROOT' => 'localhost:8888', 
    'RELATIVE_PATH_BASE' => '/libraries/backend/Data/examples', 
    'RELATIVE_PATH_APP' => '/libraries/backend/Data', 
    'RELATIVE_PATH_LIBRARY' => '/libraries/backend/Data/vendor', 
    'RELATIVE_PATH_HELPERS' => '/libraries/backend/Data/examples', 
    'RELATIVE_PATH_TEMPLATE' => '/libraries/backend/Data/examples/templates', 
    'RELATIVE_PATH_CONFIG' => '/libraries/backend/Data/examples/config', 
    'RELATIVE_PATH_PAGES' => '/libraries/backend/Data/examples/pages', 
    'RELATIVE_PATH_ASSET' => '/libraries/backend/Data/examples/assets', 
    'RELATIVE_PATH_ASSET_IMG' => '/libraries/backend/Data/examples/assets/img', 
    'RELATIVE_PATH_ASSET_CSS' => '/libraries/backend/Data/examples/assets/css', 
    'RELATIVE_PATH_ASSET_JS' => '/libraries/backend/Data/examples/assets/js', 
    'LOCAL_PATH_BASE' => '/var/www/libraries/backend/Data/examples', 
    'LOCAL_PATH_APP' => '/var/www/libraries/backend/Data', 
    'LOCAL_PATH_LIBRARY' => '/var/www/libraries/backend/Data/vendor', 
    'LOCAL_PATH_HELPERS' => '/var/www/libraries/backend/Data/examples', 
    'LOCAL_PATH_TEMPLATE' => '/var/www/libraries/backend/Data/examples/templates', 
    'LOCAL_PATH_CONFIG' => '/var/www/libraries/backend/Data/examples/config', 
    'LOCAL_PATH_PAGES' => '/var/www/libraries/backend/Data/examples/pages', 
    'LOCAL_PATH_ASSET' => '/var/www/libraries/backend/Data/examples/assets', 
    'LOCAL_PATH_ASSET_IMG' => '/var/www/libraries/backend/Data/examples/assets/img', 
    'LOCAL_PATH_ASSET_CSS' => '/var/www/libraries/backend/Data/examples/assets/css', 
    'LOCAL_PATH_ASSET_JS' => '/var/www/libraries/backend/Data/examples/assets/js', 
    'HTTP_PATH_BASE' => 'localhost:8888/libraries/backend/Data/examples', 
    'HTTP_PATH_APP' => 'localhost:8888/libraries/backend/Data', 
    'HTTP_PATH_LIBRARY' => false, 
    'HTTP_PATH_HELPERS' => false, 
    'HTTP_PATH_TEMPLATE' => false, 
    'HTTP_PATH_CONFIG' => false, 
    'HTTP_PATH_PAGES' => false, 
    'HTTP_PATH_ASSET' => 'localhost:8888/libraries/backend/Data/examples/assets', 
    'HTTP_PATH_ASSET_IMG' => 'localhost:8888/libraries/backend/Data/examples/assets/img', 
    'HTTP_PATH_ASSET_CSS' => 'localhost:8888/libraries/backend/Data/examples/assets/css', 
    'HTTP_PATH_ASSET_JS' => 'localhost:8888/libraries/backend/Data/examples/assets/js', 
    'REQUEST_QUERY' => false, 
    'REQUEST_METHOD' => 'GET', 
    'REQUEST_STATUS' => false, 
    'REQUEST_PROTOCOL' => 'http://', 
    'REQUEST_PATH' => '/', 
    'REQUEST_PATH_STRIP_QUERY' => '/', 
    'PRODUCTION' => false, 
    'PAGE_PATH_DEFAULT' => '/index', 
    'PAGE_PATH' => '/index', 
) 
Các vấn đề liên quan