在PHP中合并目录和文件名(等效于.Net中的Path.Combine)

2021/01/14 04:41 · php ·  · 0评论

这应该是一个简单的问题,但是我不记得相关的API。在google上用“合并目录名php ”进行的搜索不会产生任何结果。因此,我想我通过提出这个问题来为自己和编程社区提供服务。这是Google和DDG返回的头条新闻!

如何在PHP中结合目录和文件名以形成完整的文件路径?假设目录名为“ D:\setup program”,文件名为“ mj.txt”。该方法应该在Windows“ D:\setup program\mj.txt上返回我当然,该方法应该在Linux或其他OS中返回正确的文件路径。

.Net中的相关功能是Path.Combine,但是在PHP中,即使我之前一定已经看过它,也想不起来。

$filepath = $path . DIRECTORY_SEPARATOR . $file;

尽管在较新版本的PHP中,斜杠的走法并不重要,因此始终使用正斜杠是可以的。

您可以使用来获得正确的绝对路径realpath(),这还将删除多余的斜杠之类的内容并解析诸如的引用../如果路径无效,它将返回false。

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

$fullPath = join(DIRECTORY_SEPARATOR, array($directoryPath, $fileName));

所有给出的答案都不会占用中的空值$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;
    }

}

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

您可以将它与php常量连接起来DIRECTORY_SEPARATOR,也可以只使用正斜杠。Windows可能不会介意= D

这并不完全是您想要的,但它应该获得一系列路径零件,然后使用DIRECTORY_SEPARATOR联接零件,然后使用DIRECTORY_SEPARATOR拆分联接的零件并删除空的路径零件。它应该返回由DIRECTORY_SEPARATOR连接的其余路径部分。

 function path_combine($paths) {
  for ($i = 0; $i < count($paths); ++$i) {
    $paths[$i] = trim($paths[$i]);
  }

  $dirty_paths = explode(DIRECTORY_SEPARATOR, join(DIRECTORY_SEPARATOR, $paths));
  for ($i = 0; $i < count($dirty_paths); ++$i) {
    $dirty_paths[$i] = trim($dirty_paths[$i]);
  }

  $unslashed_paths = array();

  for ($i = 0; $i < count($dirty_paths); ++$i) {
    $path = $dirty_paths[$i];
    if (strlen($path) == 0) continue;
    array_push($unslashed_paths, $path);
  }

  $first_not_empty_index = 0;
  while(strlen($paths[$first_not_empty_index]) == 0) {
    ++$first_not_empty_index;
  }
  $starts_with_slash = $paths[$first_not_empty_index][0] == DIRECTORY_SEPARATOR;

  return $starts_with_slash
    ? DIRECTORY_SEPARATOR . join(DIRECTORY_SEPARATOR, $unslashed_paths)
    : join(DIRECTORY_SEPARATOR, $unslashed_paths);
}

用法示例:

$test = path_combine([' ', '/cosecheamo', 'pizze', '///// 4formaggi', 'GORGONZOLA']);
echo $test;

将输出:

/cosecheamo/pizze/4formaggi/GORGONZOLA

试试这个功能。我使用此功能来满足自己的需求。

如果要检查路径,必须将$ isReal设置为true

  public static function path($base, $com = null, $isReal = false)
  {
    if(substr($base, -1)!=DIRECTORY_SEPARATOR) $base.=DIRECTORY_SEPARATOR;
    if($com) $base.=$com;
    $base = preg_replace('/(\/+|\\\\+)/', DIRECTORY_SEPARATOR, $base);
    while(preg_match('/(\/[\w\s_-]+\/\.\.)/', $base)){
      $base = preg_replace('/(\/[\w\s_-]+\/\.\.)/', "", $base);
      if(preg_match('/\/\.\.\//', $base))
        throw new \Exception("Error directory don't have parent folder!", 1);
    }
    if($isReal){
      $base = realpath($base);
      if(is_dir($base)) $base .= DIRECTORY_SEPARATOR;
    }
    return $base;
  }

输出示例:

var_dump(Combine::path("www///system", "Combine/../"));
// string(11) "www/system/"

var_dump(Combine::path("System", "Combine/../", true));
// string(40) "/home/snow/Desktop/localhost/www/System/"

var_dump(Combine::path("System", "Combine", true));
// string(48) "/home/snow/Desktop/localhost/www/System/Combine/"

var_dump(Combine::path("System", "Combine/notPath", true)); // if you try to create a path that does not exist
// bool(false)

var_dump(Combine::path("System", "Combine/class.Combine.php", true)); // you can also select a file
//string(65) "/home/snow/Desktop/localhost/www/System/Combine/class.Combine.php"

var_dump(Combine::path("/home/testuser\\badPath///////repair"));
// string(30) "/home/testuser/badPath/repair/"

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 ""
本文地址:http://php.askforanswer.com/zaiphpzhonghebingmuluhewenjianmingdengxiaoyu-netzhongdepath-combine.html
文章标签:
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!