2010-07-11 37 views
39

Trên máy chủ cục bộ. Tôi có cấu trúc thư mục sau:Làm thế nào để bạn có được PHP, liên kết tượng trưng và __FILE__ làm việc cùng nhau độc đáo?

/share/www/trunk/wp-content/plugins/otherfolders

/share/www/portfolio/wp-content/symlink

đâu symlink là một liên kết tượng trưng đến /trunk/.../plugins/. Về cơ bản, điều này là bởi vì tôi cần phải thử nghiệm nhiều cài đặt WordPress và thiết lập chúng, nhưng tôi không muốn phải di chuyển các plugin xung quanh và sao chép và dán chúng ở khắp mọi nơi.

Tuy nhiên, đôi khi tôi cần phải bò lên cây thư mục để bao gồm một tập tin cấu hình:

$root = dirname(dirname(dirname(dirname(__FILE__)))); 
     if (file_exists($root.'/wp-load.php')) { 
      // WP 2.6 
      require_once($root.'/wp-load.php'); 
     } 

Thư mục luôn luôn quyết tâm:

/share/www/trunk

Ngay cả khi các plugin đã được thực hiện và đưa vào

/share/www/portfolio/.

Có thể trong PHP để bao gồm các tệp trong thư mục share/www/portfolio từ tập lệnh thực thi trong liên kết tượng trưng đến thư mục /share/www/trunk/.../plugins không?

Trong khi sự cố này chỉ xảy ra trên máy chủ thử nghiệm của tôi, tôi muốn có giải pháp phân phối an toàn để thu thập thông tin lên mức phụ không phải là tùy chọn.

+0

Bạn có biết nơi bạn đang thực hiện doanh nghiệp __FILE__ có liên quan đến điểm vào không? $ _SERVER ['SCRIPT_FILENAME'] tương đương với gì trong ngữ cảnh ví dụ của bạn? – Shabbyrobe

+0

Bingo. Tôi biết chính xác có bao nhiêu thư mục tôi cần thu thập thông tin. Tôi chỉ cần có thư mục cơ bản đúng. Đăng câu trả lời và tiền thưởng là của bạn. –

+0

Một ý tưởng khác sẽ là sử dụng các liên kết cứng thay vì các liên kết tượng trưng. Hoặc là có một lý do tại sao bạn cần symlink (giống như mountpoint khác, vv)? – JochenJung

Trả lời

28

Sự cố tôi thấy với mã của bạn là tự động giải quyết các vấn đề liên quan đến các liên kết tượng trưng __FILE__.

Từ Manual PHP trên Magic Constants

... Kể từ PHP 4.0.2, __FILE__ luôn chứa một đường dẫn tuyệt đối với liên kết tượng trưng giải quyết ...

Bạn có thể thử sử dụng $_SERVER["SCRIPT_FILENAME"] để thay thế.

$root = realpath(dirname(dirname(dirname(dirname($_SERVER["SCRIPT_FILENAME"]))))); 
    if (file_exists($root.'/wp-load.php')) { 
     // WP 2.6 
     require_once($root.'/wp-load.php'); 
    } 

Lưu ý rằng tôi đã thêm chức năng realpath() vào thư mục gốc. Tùy thuộc vào thiết lập của bạn, bạn có thể hoặc không cần nó.

CHỈNH SỬA: Sử dụng $_SERVER["SCRIPT_FILENAME"] thay vì $_SERVER["PHP_SELF"] cho đường dẫn hệ thống tệp.

+0

PHP_SELF chỉ cung cấp giá trị của tệp xử lý hiện tại. Kết quả cuối cùng cần phải là một đường dẫn tuyệt đối không phải là một URI. –

+0

Tệ của tôi ... Tôi đã thử nghiệm ban đầu từ CLI. Thay vào đó, hãy sử dụng $ _SERVER ["SCRIPT_FILENAME"]? Điều đó làm việc trong môi trường của tôi. Nếu điều đó không có tác dụng gì về việc thêm $ _SERVER ["DOCUMENT_ROOT"] vào $ _SERVER ["PHP_SELF"]? – pferate

+0

Sau đây là lỗi cho vấn đề của bạn: https://bugs.php.net/bug.php?id = 46260 Đáng buồn thay, PHP sẽ không thay đổi theo cách này, đó là một lỗi theo ý kiến ​​của tôi. –

0

Nếu tôi đã cố gắng để giải quyết việc này, tôi muốn chia __FILE__ dọc theo bit đường dẫn và tạo ra một SplFileInfo cho mỗi đường đi, thử nghiệm với isDirisLink, sau đó cố gắng để xác định làm thế nào để xử lý tái thiết của con đường khi nó đã được biết là khác với dự kiến ​​để bạn có thể kéo từ thư mục bên phải. (Nếu bạn có nhiều loại thủ tục hơn, có is_diris_link.)

Điều đó đang được nói, tôi nghĩ bạn đã loại bỏ giải pháp này. Có lẽ các công cụ đủ thông minh để làm điều đó cho bạn. Hãy thử so sánh kết quả của getRealPath tới getPath? getRealPath rõ ràng nói rằng nó giải quyết các liên kết tượng trưng, ​​trong khi getPath không nói rõ điều đó.

Thậm chí sau đó, sniffing này có thể không được an toàn trên các trang web của khách hàng, tùy thuộc vào người dẫn chương trình là. Tôi đã nhìn thấy một số khá sáng tạo chia sẻ các thiết lập hệ thống tập tin lưu trữ. Bạn có thể thêm một kiểm tra để php_uname và kéo ra tên máy của máy, và nếu nó không phải là hộp dev của bạn, không làm công việc phụ.

+1

Thật không may, 'getRealPath' và' getPath' đều xuất ra thư mục '/ trunk /'. –

1

Trình thông dịch PHP giải quyết các liên kết tượng trưng trước khi xử lý chúng. Bạn có thể tự làm điều này với chức năng readlink. PHP giải quyết các liên kết vì nó hiệu quả hơn đối với các hàm *_once và bộ đệm mã như APC, Xcache, v.v.

Điều bạn cần là một cách khác để tìm nơi cài đặt cụ thể lưu trữ tệp của nó. Tôi khuyên bạn nên sử dụng {$_SERVER['DOCUMENT_ROOT']}/wp-content/wp-load.php giả /share/www/portfolio là tài liệu gốc.

+0

Gốc tài liệu không may/share/www/ –

2

Bạn có thể sử dụng đoạn mã này để nhận đường dẫn nơi các liên kết tượng trưng không được giải quyết. Nếu bạn không có bash, có thể có một lệnh khác bạn có thể sử dụng, nhưng nó hoạt động trên môi trường Linux.

Tôi nghĩ rằng đó là một sơ suất mà php giải quyết các liên kết tượng trưng trong FILE, vì không có cách nào để có được đường dẫn với các liên kết tượng trưng. Nếu không, chúng tôi có thể dễ dàng có được nó bằng cách sử dụng realpath.

Ồ tốt.

<?php 
$output = array(); 
exec('pwd', &$output); 
define('__LINK__', $output[0].substr(__FILE__, strpos(__FILE__, DIRECTORY_SEPARATOR))); 
?> 
+1

'pwd' trả về giá trị phụ thuộc vào thư mục làm việc hiện tại; Để làm việc đúng cách, bạn nên thay đổi directiry làm việc trước: cd/var/www/wp-content/themes/twenty_twelve/&& php script.php – AndreyP

+0

Tôi đã xóa '&', và '$ output [0]' làm việc cho tôi . –

2

Trong một số trường hợp có thể của nó để thay đổi thư mục làm việc và sử dụng getenv ('PWD'):

$root = dirname(dirname(dirname(getenv('PWD')))); 
if (file_exists($root.'/wp-load.php')) { 
    // WP 2.6 
    require_once($root.'/wp-load.php'); 
} 

Và thay đổi thư mục làm việc trước khi chạy đoạn mã này:

cd /var/www/wp-content/themes/twenty_twelve/ && php script.php 
1

Đây là giải pháp cho vấn đề đó: https://github.com/logical-and/symlink-detective

$root = dirname(dirname(dirname(dirname(__FILE__)))); 
    if (file_exists(SymlinkDetective::detectPath($root.'/wp-load.php'))) { 
     // WP 2.6 
     require_once(SymlinkDetective::detectPath($root.'/wp-load.php')); 
    } 

hoặc bạn có thể thử rằng

try { 
    $root = dirname(dirname(dirname(dirname(__FILE__)))); 
    require_once SymlinkDetective::detectPath($root.'/wp-load.php', '', 
    false /* this would throw an exception if file doesn't exists */); 
} 
catch (Exception $e) { 
    // nothing to do if file doesn't exists 
} 
+1

Tôi thực sự không hiểu tại sao bạn xóa câu trả lời của tôi. Tôi đã viết giải pháp cho vấn đề này, tôi đã đưa ra các ví dụ về cách nó có thể được sử dụng, tôi đã viết câu trả lời đó. Hãy thử làm như vậy, thay vì xóa bài đăng của tôi hoặc cho tôi biết ít nhất tại sao? Thông tin của tôi có hữu ích không? – And

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