首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >路径的PHP连接

路径的PHP连接
EN

Stack Overflow用户
提问于 2011-07-25 00:37:33
回答 3查看 7.7K关注 0票数 4

PHP内部有没有连接路径的函数?合并几个路径(绝对路径和相对路径)的可能性是什么?

代码语言:javascript
复制
//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/”作为前缀?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-07-25 00:58:45

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

规范化是:

删除尾随分隔符(我已选择支持,但从不返回反斜杠间接:/../

  • Removing重复分隔符:/home/www/uploads//file.ext

  • Always
  • 分隔符。

我已经写了一个函数来实现这一点。我现在还无法访问这些代码,但自己编写它也不是那么难。

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

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

来回答您的问题:如果只使用/和,路径连接可能会非常容易假设目录没有尾部分隔符。“没有尾部分隔符”似乎是一个很好的假设,因为像dirname这样的函数删除了尾部分隔符。

这样做总是安全的:$dir . "/" . $file

即使结果路径是/home/uploads/../uploads//my_uploads/myfile.ext,它仍然可以很好地工作。

当您需要将路径存储在某个地方时,规范化将变得非常有用。因为你有这个归一化函数,所以你可以做这些假设。

另一个有用的函数是创建相对路径的函数。

  • /files/uploads
  • /files/uploads/my_uploads/myfile.ext

从这两个路径派生出文件的相对路径是很有用的。

realpath

我发现realpath的性能非常繁重。如果你只调用一次,这并不是很糟糕,但如果你在某个地方循环调用,你会得到相当大的成功。请记住,每个realpath调用也是对文件系统的调用。而且,如果你传入一些愚蠢的东西,它会简单地返回false,我宁愿让它抛出一个异常。

对我来说,realpath函数是坏函数的一个很好的例子,因为它做两件事: 1.它标准化路径,2.它检查路径是否存在。当然,这两个函数都很有用,但它们必须分开。它也不区分文件和目录。对于windows来说,这通常不是问题,但对于Linux来说,这可能是个问题。

我认为在Windows上使用realpath("")有一些奇怪的地方。我认为它将返回\\ -这可能是非常不可接受的。

代码语言:javascript
复制
/**
 * 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);
}
票数 5
EN

Stack Overflow用户

发布于 2011-07-25 00:41:00

如果该路径确实存在,则可以使用realpath将其展开。

代码语言:javascript
复制
echo realpath("/home/../home/dogbert")
/home/dogbert
票数 4
EN

Stack Overflow用户

发布于 2014-08-06 12:00:50

realpath的另一个问题是它不适用于URL,但是连接的逻辑本质上是相同的(在两个连接的组件之间应该恰好有一个斜杠)。显然,开头有两个斜杠的协议部分是此规则的一个例外。但是,一个将URL的各个部分连接在一起的函数将会非常好。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6808143

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档