PHP 有一个很好的realpath()
函数,可以将类似的东西转换/dir1/dir2/../dir3/filename
为/dir1/dir3/filename
. 这个函数的“问题”是,如果/dir1/dir3/filename
不是一个实际文件,而只是一个到另一个文件的链接,PHP 会跟随那个链接并返回实际文件的真实路径。
但是,我实际上需要获取链接本身的真实路径。我所需要的只是解决/dir/..
路径中的复杂性。我该怎么做?
PHP 有一个很好的realpath()
函数,可以将类似的东西转换/dir1/dir2/../dir3/filename
为/dir1/dir3/filename
. 这个函数的“问题”是,如果/dir1/dir3/filename
不是一个实际文件,而只是一个到另一个文件的链接,PHP 会跟随那个链接并返回实际文件的真实路径。
但是,我实际上需要获取链接本身的真实路径。我所需要的只是解决/dir/..
路径中的复杂性。我该怎么做?
为您的要求编写了一个函数。
function realpath_no_follow_link($str) {
if (is_link($str)) {
$pathinfo = pathinfo($str);
return realpath_no_follow_link($pathinfo['dirname']) . '/' .$pathinfo['basename'];
}
return realpath($str);
}
我希望找到一个现有的 PHP 函数来执行此操作,或者按照 xdazz 的答案进行一些简单的操作(但这实际上会按照我想要的方式工作)。由于找不到这样的答案,我编写了自己的脏函数。我很高兴听到您的意见和改进建议!
// return the contracted path (e.g. '/dir1/dir2/../dir3/filename' => '/dir1/dir3/filename')
// $path: an absolute or relative path
// $rel: the base $path is given relatively to - if $path is a relative path; NULL would take the current working directory as base
// return: the contracted path, or FALSE if $path is invalid
function contract_path($path, $rel = NULL) {
if($path == '') return FALSE;
if($path == '/') return '/';
if($path[strlen($path) - 1] == '/') $path = substr($path, 0, strlen($path) - 1); // strip trailing slash
if($path[0] != '/') { // if $path is a relative path
if(is_null($rel)) $rel = getcwd();
if($rel[strlen($rel) - 1] != '/') $rel .= '/';
$path = $rel . $path;
}
$comps = explode('/', substr($path, 1)); // strip initial slash and extract path components
$res = Array();
foreach($comps as $comp) {
if($comp == '') return FALSE; // double slash - invalid path
if($comp == '..') {
if(count($res) == 0) return FALSE; // parent directory of root - invalid path
array_pop($res);
}
elseif($comp != '.') $res[] = $comp;
}
return '/' . implode('/', $res);
}
你可以试试 abspath() 函数。