PHP路径串联
是否有用于路径连接的PHP内部函数?我必须合并多个路径(绝对路径和相对路径)的可能性有哪些 好的,这个例子有一个简单的解决方案,但是如果有不同的字典分隔符或者一些路径稍微复杂一点呢 有没有这样的修剪解决方案:/home/uploads/。/uploads/tmp=>/home/uploads/tmp 与平台无关的path concat函数是什么样子的PHP路径串联,php,class,path,relative-path,absolute-path,Php,Class,Path,Relative Path,Absolute Path,是否有用于路径连接的PHP内部函数?我必须合并多个路径(绝对路径和相对路径)的可能性有哪些 好的,这个例子有一个简单的解决方案,但是如果有不同的字典分隔符或者一些路径稍微复杂一点呢 有没有这样的修剪解决方案:/home/uploads/。/uploads/tmp=>/home/uploads/tmp 与平台无关的path concat函数是什么样子的 相对路径应该以“/”开头作为前缀,还是“home/path/img/”是常用方式?如果路径确实存在,可以使用realpath对其进行扩展 echo
相对路径应该以“/”开头作为前缀,还是“home/path/img/”是常用方式?如果路径确实存在,可以使用
realpath
对其进行扩展
echo realpath("/home/../home/dogbert")
/home/dogbert
我自己也遇到了这个问题,主要是关于路径的规范化 标准化是:
- 一个分隔符(我选择支持,但从不返回反斜杠
)\\
- 解析间接寻址:
/../
- 删除重复分隔符:
/home/www/uploads//file.ext
- 务必拆下尾部分离器
/
,因此为了简单起见,我一直在使用它,但我想使用什么分隔符并不重要
回答您的问题:如果您总是使用
/
并且假设一个目录没有尾随分隔符,那么路径连接会非常容易“无尾随分隔符”似乎是一个很好的假设,因为像dirname
这样的函数会删除尾随分隔符
这样做总是安全的:$dir。"/" . $文件
即使结果路径是/home/uploads//uploads//my_uploads/myfile.ext
,它仍然可以正常工作
当需要将路径存储到某个位置时,规范化变得非常有用。因为你有这个标准化函数,你可以做出这些假设
另一个有用的函数是生成相对路径的函数
- /文件/上传
- /文件/uploads/my_uploads/myfile.ext
realpath 我发现
realpath
的性能非常高。如果你只打一次电话也没那么糟糕,但是如果你在某个地方打一个循环,你会得到相当大的成功。请记住,每个realpath
调用也是对文件系统的调用。此外,它将简单地返回false
如果您传入一些愚蠢的内容,我宁愿让它抛出一个异常
对我来说,realpath
函数是坏函数的一个好例子,因为它做了两件事:1。它规范化了路径和2。它检查路径是否存在。当然,这两个函数都很有用,但它们必须分开。它也不区分文件和目录。对于windows来说,这通常不是问题,但对于Linux来说可能是问题
我认为在Windows上使用realpath(“”
)时有一些奇怪之处。我认为它将返回\\
——这是完全不可接受的
/**
*此函数是realpath的适当替代品
*它将只规范化路径并解决间接(…和。)
*标准化包括:
*-始终使用直接分隔符/
*-不存在尾随目录分隔符
*@param$path
*@返回字符串
*/
函数normalize_path($path){
$parts=preg\u split(“:[\\/]:”,$path);//在已知的目录分隔符上拆分
//解析相对路径
对于($i=0;$i0&&$parts[$i]==”){//删除空部分
未结算($parts[$i]);
$parts=数组_值($parts);
}
}
返回内爆(“/”,$parts);
}
/**
*从较长路径中删除基本路径。结果路径永远不会包含前导目录分隔符
*基本路径必须出现在较长的路径中
*路径将被规范化
*@抛出异常
*@param$base_路径
*@param$更长的路径
*@返回字符串规范化的相对路径
*/
函数make_relative_path($base_path,$longer_path){
$base\u path=规范化\u path($base\u path);
$longer\u path=规范化\u path($longer\u path);
如果(0!==strpos($longer\u path,$base\u path)){
抛出新异常(“无法创建相对路径,在较长路径中,基本路径不出现在0处:`.$base\u path.`,`.$longer\u path.`”);
}
返回substr($longer_path,strlen($base_path)+1);
}
realpath的另一个问题是它不适用于URL,但是连接逻辑基本上是相同的(两个连接的组件之间应该正好有一个斜杠)。显然,协议部分开头有两个斜杠,这是该规则的一个例外。但是,一个将URL的各个部分连接在一起的函数还是很好的。好的,这很酷,但是有没有办法计算出目录分隔符,或者有没有一个标准化的路径“格式”?+1,尽管它确实很重要
echo realpath("/home/../home/dogbert")
/home/dogbert
/**
* 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);
}