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:
- Thêm/loại bỏ của Windows ký tự ổ đĩa như trong
c:
.
- Xóa dấu gạch chéo.
- Chuẩn bị thư mục làm việc hiện tại cho đường dẫn tương đối.
- 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.
- 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;
}
Làm cách nào để tránh độ phân giải của liên kết tượng trưng? – LeMike
@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