PHP路径串联

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

是否有用于路径连接的PHP内部函数?我必须合并多个路径(绝对路径和相对路径)的可能性有哪些

好的,这个例子有一个简单的解决方案,但是如果有不同的字典分隔符或者一些路径稍微复杂一点呢

有没有这样的修剪解决方案:/home/uploads/。/uploads/tmp=>/home/uploads/tmp

与平台无关的path concat函数是什么样子的


相对路径应该以“/”开头作为前缀,还是“home/path/img/”是常用方式?

如果路径确实存在,可以使用
realpath
对其进行扩展

echo realpath("/home/../home/dogbert")
/home/dogbert

我自己也遇到了这个问题,主要是关于路径的规范化

标准化是:

  • 一个分隔符(我选择支持,但从不返回反斜杠
    \\
  • 解析间接寻址:
    /../
  • 删除重复分隔符:
    /home/www/uploads//file.ext
  • 务必拆下尾部分离器
我已经编写了一个函数来实现这一点。我现在没有访问该代码的权限,但自己编写代码也不难

路径是否为绝对路径对于该规范化函数的实现并不重要,只要注意前导分隔符就可以了

我不太担心操作系统的依赖性。Windows和Linux PHP都理解
/
,因此为了简单起见,我一直在使用它,但我想使用什么分隔符并不重要


回答您的问题:如果您总是使用
/
并且假设一个目录没有尾随分隔符,那么路径连接会非常容易“无尾随分隔符”似乎是一个很好的假设,因为像
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);
}