PHP内部有没有连接路径的函数?合并几个路径(绝对路径和相对路径)的可能性是什么?
//Example:
$path1="/usr/home/username/www";
$path2="domainname";
$path3="images/thumbnails";
$domain="exampledomain.com";
//As example: Now I want to create a new path (domain + path3) on the fly.
$result = $domain.DIRECTORY_SEPARATOR.$path3好的,这个例子有一个简单的解决方案,但是如果有不同的字典分隔符或者一些路径有点复杂怎么办?
有没有像这样修剪它的现有解决方案: /home/uploads/../uploads/tmp => /home/uploads/TMP....
路径连接函数的独立于平台的版本会是什么样子呢?
相对路径应该以"./“作为前缀还是以"home/ path /img/”作为前缀?
发布于 2011-07-25 00:58:45
我自己也遇到了这个问题,主要是关于路径的规范化。
规范化是:
删除尾随分隔符(我已选择支持,但从不返回反斜杠间接:/../
/home/www/uploads//file.ext
我已经写了一个函数来实现这一点。我现在还无法访问这些代码,但自己编写它也不是那么难。
路径是否是绝对的对于这个规范化函数的实现来说并不重要,只要注意前导分隔符就可以了。
我并不太担心操作系统的依赖性。Windows和Linux PHP都理解/,所以为了简单起见,我只是一直使用它--但我猜使用什么分隔符并不重要。
来回答您的问题:如果只使用/和,路径连接可能会非常容易假设目录没有尾部分隔符。“没有尾部分隔符”似乎是一个很好的假设,因为像dirname这样的函数删除了尾部分隔符。
这样做总是安全的:$dir . "/" . $file。
即使结果路径是/home/uploads/../uploads//my_uploads/myfile.ext,它仍然可以很好地工作。
当您需要将路径存储在某个地方时,规范化将变得非常有用。因为你有这个归一化函数,所以你可以做这些假设。
另一个有用的函数是创建相对路径的函数。
从这两个路径派生出文件的相对路径是很有用的。
realpath
我发现realpath的性能非常繁重。如果你只调用一次,这并不是很糟糕,但如果你在某个地方循环调用,你会得到相当大的成功。请记住,每个realpath调用也是对文件系统的调用。而且,如果你传入一些愚蠢的东西,它会简单地返回false,我宁愿让它抛出一个异常。
对我来说,realpath函数是坏函数的一个很好的例子,因为它做两件事: 1.它标准化路径,2.它检查路径是否存在。当然,这两个函数都很有用,但它们必须分开。它也不区分文件和目录。对于windows来说,这通常不是问题,但对于Linux来说,这可能是个问题。
我认为在Windows上使用realpath("")有一些奇怪的地方。我认为它将返回\\ -这可能是非常不可接受的。
/**
* This function is a proper replacement for realpath
* It will _only_ normalize the path and resolve indirections (.. and .)
* Normalization includes:
* - directiory separator is always /
* - there is never a trailing directory separator
* @param $path
* @return String
*/
function normalize_path($path) {
$parts = preg_split(":[\\\/]:", $path); // split on known directory separators
// resolve relative paths
for ($i = 0; $i < count($parts); $i +=1) {
if ($parts[$i] === "..") { // resolve ..
if ($i === 0) {
throw new Exception("Cannot resolve path, path seems invalid: `" . $path . "`");
}
unset($parts[$i - 1]);
unset($parts[$i]);
$parts = array_values($parts);
$i -= 2;
} else if ($parts[$i] === ".") { // resolve .
unset($parts[$i]);
$parts = array_values($parts);
$i -= 1;
}
if ($i > 0 && $parts[$i] === "") { // remove empty parts
unset($parts[$i]);
$parts = array_values($parts);
}
}
return implode("/", $parts);
}
/**
* Removes base path from longer path. The resulting path will never contain a leading directory separator
* Base path must occur in longer path
* Paths will be normalized
* @throws Exception
* @param $base_path
* @param $longer_path
* @return string normalized relative path
*/
function make_relative_path($base_path, $longer_path) {
$base_path = normalize_path($base_path);
$longer_path = normalize_path($longer_path);
if (0 !== strpos($longer_path, $base_path)) {
throw new Exception("Can not make relative path, base path does not occur at 0 in longer path: `" . $base_path . "`, `" . $longer_path . "`");
}
return substr($longer_path, strlen($base_path) + 1);
}发布于 2011-07-25 00:41:00
如果该路径确实存在,则可以使用realpath将其展开。
echo realpath("/home/../home/dogbert")
/home/dogbert发布于 2014-08-06 12:00:50
realpath的另一个问题是它不适用于URL,但是连接的逻辑本质上是相同的(在两个连接的组件之间应该恰好有一个斜杠)。显然,开头有两个斜杠的协议部分是此规则的一个例外。但是,一个将URL的各个部分连接在一起的函数将会非常好。
https://stackoverflow.com/questions/6808143
复制相似问题