2012-03-16 30 views
7

Tôi có một vài tập tin trong thư mục web của tôi, trong đó có hai:Làm thế nào để có được đường dẫn ban đầu của một liên kết tượng trưng trong PHP?

  • /mydocroot/include/somesubdir/include.inc.php
  • /mydocroot/include/settings.inc.php

nơi somesubdir là một liên kết tượng trưng đến thư mục khác trên đĩa của tôi, với đường dẫn có tên, eh, giả sử /anywhere/else.

Bên include.inc.php, một cái gì đó như thế này có chép rằng:

<?php 

require_once "../settings.inc.php"; 

?> 

Theo tôi, đó nên bao gồm /mydocroot/include/settings.php ... Nhưng đoán điều gì xảy ra: PHP cố gắng bao gồm /anywhere/settings.inc.php, thay vì/mydocroot/include/settings.inc.php.

Dường như PHP tự động giải quyết các liên kết tượng trưng.

Làm cách nào để tránh điều này và bao gồm các cài đặt .inc.php của tôi?

+0

'echo __DIR __;' bên trong '/ include.inc.php' in là gì? –

+0

@Rocket: 'echo __DIR __;' in '/ anywhere/else'. –

Trả lời

2

Giải pháp chuyển tiếp thẳng nhất là luôn sử dụng đường dẫn tuyệt đối. Có nhiều cách bạn có thể thực hiện việc này, từ khó mã hóa đường dẫn mỗi khi bạn cần, để mã hóa đường dẫn một lần ở đầu tập lệnh và tham khảo, để tự động tìm và đặt nó một lần ở đầu kịch bản.

Tùy chọn thứ ba là những gì hầu hết các kệ CMS sử dụng để có thể chạy mà không có kiến ​​thức đầy đủ về cấu trúc tệp của bạn.

Tại sao bạn sử dụng thư mục được liên kết tượng trưng theo cách này?

+0

Bạn đã ghi chú trong nhận xét của mình về @adam; Tôi thực sự sử dụng một liên kết tượng trưng bởi vì tôi không muốn có nhiều phiên bản của cùng một tệp trên đĩa cứng của mình. Đó là mã được chia sẻ. –

+0

Đủ công bằng, đó là lý do tôi hỏi. Bạn vẫn có thể sử dụng câu trả lời của tôi. Chỉ cần thiết lập hoặc tìm nó trước, trước khi bao gồm '/mydocroot/include/somesubdir/include.inc.php ->/anywhere/else/include.inc.php'. Có lẽ không phải lý tưởng, nhưng đó là tất cả những gì bạn có thể hiểu được. – Jason

+1

Nó có vẻ là cách duy nhất nó có thể được thực hiện. Đây là cách tôi tạo ra cách giải quyết: Tôi đã tạo một tệp (gọi nó là ** symlink.php **) bên trong **/mydocroot/include/**, chỉ chứa một câu lệnh: 'define (" ROOT ", __DIR__) ; 'Sau đó trong ** include.inc.php ** tôi kiểm tra xem hằng số' ROOT' đã được xác định hay chưa. Nếu có, hãy sử dụng đường dẫn đó. –

0

Bạn có thể sử dụng is_link để kiểm tra xem tệp có phải là liên kết tượng trưng hay không. Nếu có, hãy sử dụng readlink để có được mục tiêu tuyệt đối.

Nhưng, trong mười năm phát triển php, tôi chưa bao giờ có nguyên nhân sử dụng liên kết tượng trưng. Như Jason gợi ý, tôi đã luôn định nghĩa hoặc suy ra một đường dẫn tuyệt đối một lần, sau đó sử dụng nó trong suốt ứng dụng của tôi để làm cho tất cả các đường dẫn tệp tuyệt đối.

+2

Vấn đề là nó sẽ không hoạt động ngược, cách anh ta đang cố gắng làm điều đó. Về cơ bản, tệp trong thư mục được liên kết không có cách nào để xác định rằng thư mục trong thư mục được truy cập trong ngữ cảnh được liên kết, thay vì trực tiếp thông qua hệ thống tệp theo nghĩa đen. Đối với việc sử dụng các liên kết tượng trưng, ​​nó có thể có ý nghĩa trong các bối cảnh hạn chế. Cách duy nhất nó có ý nghĩa trong bối cảnh của OP là nếu tập tin đang được chia sẻ giữa nhiều máy chủ ảo. – Jason

3

Tôi vừa gặp sự cố tương tự. Bạn có thể làm điều đó bằng cách sử dụng biến số $_SERVER['SCRIPT_FILENAME'], hiển thị tệp được yêu cầu, vì vậy trong trường hợp của bạn, nó sẽ là /mydocroot/include/somesubdir/include.inc.php, ngay cả khi somesubdir là một liên kết tượng trưng. Để đưa tập tin đó là một trong những mức thấp hơn thay vì làm

require_once "../settings.inc.php"; 

làm điều này:

require_once dirname(dirname($_SERVER['SCRIPT_FILENAME'])).DIRECTORY_SEPARATOR."settings.inc.php" 

Documentation about $_SERVER variables

1

Giải pháp là để tạo ra một biến basepath.Cách tốt nhất để làm điều này là để bao gồm những điều sau đây ở phía trên cùng của kịch bản của bạn và sau đó tham khảo nó

$basepath = dirname(dirname($_SERVER['SCRIPT_FILENAME'])).DIRECTORY_SEPARATOR; 

Sau đó, bạn có thể tham khảo các basepath trong bao gồm bạn, đòi hỏi, vv Vì vậy,

include "../myscript.php"; 

sẽ trở thành,

include $basepath."myscript.php"; 

Nếu bạn đang trở lại đánh dấu thêm nữa, bạn sẽ có điều này:

include "../../myscript.php"; 

Sẽ trở thành,

include $basepath."../myscript.php"; 

Bạn phải tổ chức năng dir_name hai lần, cộng thêm một lần nữa cho mỗi thư mục bổ sung mà bạn cần phải backtick qua. Bạn PHẢI nhận được tất cả các cách trở lại thư mục nơi liên kết tượng trưng tồn tại.

Tôi xem vấn đề này là một lỗ hổng thiết kế lớn với PHP. Tôi không thể nghĩ về một trường hợp duy nhất mà truy cập các tập tin backticked liên quan đến tập tin thực tế sẽ là mong muốn. Trong mọi tình huống, bao gồm cả lưu trữ ảo, nó CHỈ có ý nghĩa để quay trở lại dọc theo đường dẫn được liên kết, không bao giờ là đường dẫn đích.

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