2011-06-29 22 views
5

Có cách nào trong PHP cách xác định đường dẫn tuyệt đối cho đường dẫn tương đối mà không thực sự giải quyết các liên kết tượng trưng không? Một cái gì đó giống như hàm realpath nhưng không có độ phân giải của liên kết tượng trưng. Hoặc cách khác, có cách nào dễ dàng để kiểm tra xem người dùng (người sử dụng kịch bản PHP duyệt web của tôi để xem tệp) không vô tình bước ra khỏi thư mục chính của máy chủ ảo của Apache không? Không. (hoặc không cho phép anh ta sử dụng khó chịu. và .. trong đường dẫn)Đường dẫn tuyệt đối không có độ phân giải liên kết/Giữ người dùng trong thư mục chính

Cảm ơn!

Trả lời

2

Tôi không biết giải pháp có nguồn gốc PHP cho điều này, nhưng một trong những đẹp tuyệt đối con đường thực hiện là ở đây: http://www.php.net/manual/en/function.realpath.php#84012

+0

Làm cách nào để tránh độ phân giải của liên kết tượng trưng? – LeMike

+0

@MikePretzlaw Không giống như 'realpath', chức năng này không làm bất cứ điều gì ở cấp hệ thống tệp, bởi vì nó chỉ hoạt động trên chuỗi sửa đổi. Và đây là toàn bộ vấn đề! :-) – Karolis

0

Bạn có thể sử dụng open_basedir thiết lập ini php.ini hoặc trong khai báo máy chủ ảo (dưới dạng chỉ thị php_admin_value).

0

Dưới đây là cách tiếp cận của tôi bắt chước bản gốc realpath() mà cũng:

  1. Thêm/loại bỏ của Windows ký tự ổ đĩa như trong c:.
  2. Xóa dấu gạch chéo.
  3. Chuẩn bị thư mục làm việc hiện tại cho đường dẫn tương đối.
  4. Tùy chọn kiểm tra sự tồn tại của tệp. Trong trường hợp của một tập tin không tồn tại A) không làm gì, B) trả về một giá trị FALSE hoặc C) ném một lỗi.
  5. Tùy chọn theo các liên kết tượng trưng.

NB: Cách tiếp cận này sử dụng cụm từ thông dụng được biết là CPU đắt tiền, vì vậy tôi thích phương pháp sử dụng mảng từ http://www.php.net/manual/en/function.realpath.php#84012.

// Set constants for when a file does not exist. 
// 0: Check file existence, set FALSE when file not exists. 
define('FILE_EXISTENCE_CHECK', 0); 
// 1: Require file existence, throw error when file not exists. 
define('FILE_EXISTENCE_CHECK_REQUIRE_FILE', 1); 
// 2: Do not check file existence. 
define('FILE_EXISTENCE_CHECK_SKIP', 2); 
// Windows flag. 
define('IS_WINDOWS', preg_match('#WIN(DOWS|\d+|_?NT)#i', PHP_OS)); 
// Directory separator shortcuts. 
define('DIR_SEP', DIRECTORY_SEPARATOR); 
define('PREG_DIR_SEP', preg_quote(DIR_SEP)); 

/** 
* The original realpath() follows symbolic links which makes it harder to check 
* their paths. 
* 
* Options 
* file_existence_check: 
* - FILE_EXISTENCE_CHECK_REQUIRE_FILE: Script will break if the checked 
*  file does not exist (default). 
* - FILE_EXISTENCE_CHECK: If a file does not exist, a FALSE value will be 
*  returned. 
* - FILE_EXISTENCE_CHECK_SKIP: File existence will not be checked at all. 
* 
* follow_link: Resolve a symbolic link or not (default: FALSE). 
*/ 
function _realpath($path = NULL, $options = array()) { 
    // Merge default options with user options. 
    $options = array_merge(array(
    'file_existence_check' => FILE_EXISTENCE_CHECK_REQUIRE_FILE, 
    'follow_link' => FALSE, 
), $options); 

    // Use current working directory if path has not been defined. 
    $path = $path ? $path : getcwd(); 
    // Replace slashes with OS specific slashes. 
    $path = preg_replace('#[\\\/]#', DIR_SEP, $path); 

    // Handle `./`. Another great approach using arrays can be found at: 
    // @link p://php.net/manual/en/function.realpath.php#84012 
    $path = preg_replace('#' . PREG_DIR_SEP . '(\.?' . PREG_DIR_SEP . ')+#', DIR_SEP, $path); 
    // Handle `../`. 
    while (preg_match('#^(.*?)' . PREG_DIR_SEP . '[^' . PREG_DIR_SEP . ']+' . PREG_DIR_SEP . '\.\.($|' . PREG_DIR_SEP . '.*)#', $path, $m)) { 
    $path = $m[1] . $m[2]; 
    } 
    // Remove trailing slash. 
    $path = rtrim($path, DIR_SEP); 

    // If we are on Windows. 
    if (IS_WINDOWS) { 
    // If path starts with a lowercase drive letter. 
    if (preg_match('#^([a-z]:)(.*)#', $path, $m)) { 
     $path = strtoupper($m[1]) . $m[2]; 
    } 
    // If path starts with a slash instead of a drive letter. 
    elseif ($path[0] === DIR_SEP) { 
     // Add current working directory's drive letter, ie. "D:". 
     $path = substr(getcwd(), 0, 2) . $path; 
    } 
    } 
    else { 
    // Remove drive letter. 
    if (preg_match('#^[A-Z]:(' . PREG_DIR_SEP . '.*)#i', $path, $m)) { 
     $path = $m[1]; 
    } 
    } 

    // If path is relative. 
    if (!preg_match('#^([A-Z]:)?' . PREG_DIR_SEP . '#', $path)) { 
    // Add current working directory to path. 
    $path = getcwd() . DIR_SEP . $path; 
    } 

    // If file existence has to be checked and file does not exist. 
    if ($options['file_existence_check'] !== DSC_FILE_EXISTENCE_CHECK_SKIP && !file_exists($path)) { 
    // Return FALSE value. 
    if ($options['file_existence_check'] === DSC_FILE_EXISTENCE_CHECK) { 
     return FALSE; 
    } 
    // Or throw error. 
    else { 
     dsc_print_error('File does not exist: ' . $path); 
    } 
    } 

    // Follow sybmolic links, but only if the file exists. 
    if (!empty($options['follow_link']) && file_exists($path)) { 
    $path = readlink($path); 
    } 

    return $path; 
} 
Các vấn đề liên quan