在PHP中组合目录和文件名(相当于.Net中的Path.Combine)

Gra*_*ton 33 php

这应该是一个简单的问题,但我不记得相关的API.使用术语" 组合目录名称php " 在谷歌上搜索不会产生任何结果.所以我想通过提出这个问题,我自己和编程社区都在做服务.

如何组合目录和文件名以在PHP中形成完整的文件路径?假设目录名是" D:\setup program",文件名是" mj.txt".该方法应该返回我,在Windows" D:\setup program\mj.txt".当然该方法应该在Linux或其他操作系统中返回正确的文件路径.

.Net中的相关功能是Path.Combine,但在PHP中,我记不起来了,即使我以前一定见过它.

Tom*_*igh 36

$filepath = $path . DIRECTORY_SEPARATOR . $file;
Run Code Online (Sandbox Code Playgroud)

虽然在较新版本的PHP中,斜杠的方式无关紧要,但总是使用正斜杠是很好的.

您可以使用正确的绝对路径realpath(),这也将删除诸如额外不必要的斜线和解析引用之类的内容../.如果路径无效,它将返回false.

  • 要小心''.DIRECTORY_SEPARATOR.'foo.txt'会将相对路径转换为绝对路径. (3认同)
  • 这不等于.Net的Path.Combine,因为“ C:\”和“ file.php”将错误地组合为“ C:\\ file.php” (2认同)

sla*_*der 9

我认为最干净和灵活的方法是使用join函数和DIRECTORY_SEPARATOR常量:

$fullPath = join(DIRECTORY_SEPARATOR, array($directoryPath, $fileName));
Run Code Online (Sandbox Code Playgroud)


jor*_*jor 6

所有给出的答案都不会在 中遇到空值$directoryPath,并且不会处理重复的斜杠。虽然 PHP 确实具有很强的容错能力,但第一点可能是致命的,如果您编写干净的代码,则不应忽略第二点。

所以正确的解决方案是:

function PathCombine($one, $other, $normalize = true) {

    # normalize
    if($normalize) {
        $one = str_replace('/', DIRECTORY_SEPARATOR, $one);
        $one = str_replace('\\', DIRECTORY_SEPARATOR, $one);
        $other = str_replace('/', DIRECTORY_SEPARATOR, $other);
        $other = str_replace('\\', DIRECTORY_SEPARATOR, $other);
    }

    # remove leading/trailing dir separators
    if(!empty($one) && substr($one, -1)==DIRECTORY_SEPARATOR) $one = substr($one, 0, -1);
    if(!empty($other) && substr($other, 0, 1)==DIRECTORY_SEPARATOR) $other = substr($other, 1);

    # return combined path
    if(empty($one)) {
        return $other;
    } elseif(empty($other)) {
        return $one;
    } else {
        return $one.DIRECTORY_SEPARATOR.$other;
    }

}
Run Code Online (Sandbox Code Playgroud)

唯一的限制是第二个参数不能是绝对路径。


Kan*_*non 5

10 年后,但这也许会对下一个有所帮助。以下是我为使其与 PHP 7.4+ 兼容所做的工作。

它的工作方式与 Path.Combine 类似,只是字符串开头的 \ 或 / 不会排除前面的参数。

class Path
{
    public static function combine (): string
    {
        $paths = func_get_args();
        $paths = array_map(fn($path) => str_replace(["\\", "/"], DIRECTORY_SEPARATOR, $path), $paths);
        $paths = array_map(fn($path) => self::trimPath($path), $paths);
        return implode(DIRECTORY_SEPARATOR, $paths);
    }

    private static function trimPath(string $path): string
    {
        $path = trim($path);
        $start = $path[0] === DIRECTORY_SEPARATOR ? 1 : 0;
        $end = $path[strlen($path) - 1] === DIRECTORY_SEPARATOR ? -1 : strlen($path);
        return substr($path, $start, $end);
    }
}

Path::combine("C:\Program Files", "/Repository", "sub-repository/folder/", "file.txt");
//return "C:\Program Files\Repository\sub-repository\folder\file.txt"

Path::combine("C:\Program Files", "/Repository/", "\\sub-repository\\folder\\", "sub-folder", "file.txt");
//return "C:\Program Files\Repository\sub-repository\folder\sub-folder\file.txt"

Path::combine("C:\file.txt");
//return "C:\file.txt"

Path::combine();
//return ""
Run Code Online (Sandbox Code Playgroud)