如果文件名是UTF-8,则使PHP pathinfo()返回正确的文件名

时间:2010-12-15 15:32:02

标签: php utf-8 pathinfo

在已知为UTF-8的文件名上使用PHP的pathinfo()函数时,除非特殊字符前面有“普通”字符,否则它不会返回正确的值。

示例:
pathinfo('aä.pdf')返回:

Array
(
[dirname] => [the dir]
[basename] => aä.pdf
[extension] => pdf
[filename] => aä
)  

这很好,花花公子,但pathinfo('äa.pdf')返回:

Array
(
[dirname] => [the dir]
[basename] => a.pdf
[extension] => pdf
[filename] => a
)  

这不是我所期待的。更糟糕的是,pathinfo('ä.pdf')会返回:

Array
(
[dirname] => [the dir]
[basename] => .pdf
[extension] => pdf
[filename] => 
)  

为什么这样做?这适用于我测试的所有重音字符。

7 个答案:

答案 0 :(得分:10)

我在PHP 5.3.3 - 5.3.18中使用了这些函数来处理basename()和pathinfo()中的UTF-8问题。


if (!function_exists("mb_basename"))
{
  function mb_basename($path)
  {
    $separator = " qq ";
    $path = preg_replace("/[^ ]/u", $separator."\$0".$separator, $path);
    $base = basename($path);
    $base = str_replace($separator, "", $base);
    return $base;
  }
}
if (!function_exists("mb_pathinfo"))
{
  function mb_pathinfo($path, $opt = "")
  {
    $separator = " qq ";
    $path = preg_replace("/[^ ]/u", $separator."\$0".$separator, $path);
    if ($opt == "") $pathinfo = pathinfo($path);
    else $pathinfo = pathinfo($path, $opt);

    if (is_array($pathinfo))
    {
      $pathinfo2 = $pathinfo;
      foreach($pathinfo2 as $key => $val)
      {
        $pathinfo[$key] = str_replace($separator, "", $val);
      }
    }
    else if (is_string($pathinfo)) $pathinfo = str_replace($separator, "", $pathinfo);
    return $pathinfo;
  }
}

答案 1 :(得分:10)

在使用pathinfo之前

setlocale(LC_ALL,'en_US.UTF-8');
pathinfo($OriginalName, PATHINFO_FILENAME);
pathinfo($OriginalName, PATHINFO_BASENAME);

答案 2 :(得分:7)

这个问题的临时解决方法似乎是确保重音字符前面有一个“正常”字符,如下所示:

function getFilename($path)
{
    // if there's no '/', we're probably dealing with just a filename
    // so just put an 'a' in front of it
    if (strpos($path, '/') === false)
    {
        $path_parts = pathinfo('a'.$path);
    }
    else
    {
        $path= str_replace('/', '/a', $path);
        $path_parts = pathinfo($path);
    }
    return substr($path_parts["filename"],1);
}

请注意,我们将所有出现的'/'替换为'/ a',但这没关系,因为我们从结果的偏移量1开始返回。有趣的是,dirname的{​​{1}}部分似乎确实有效,因此不需要解决方法。

答案 3 :(得分:5)

答案 4 :(得分:1)

当处理ansi字符时,函数pathinfo正确执行。

根据这个说明,我们将(编码)输入转换为ansi charaters,然后仍然使用函数pathinfo来保存它的全部内容。

最后,我们将输出值转换(解码)为原始格式。

然后演示如下。

function _pathinfo($path, $options = null)
{
    $path = urlencode($path);
    $parts = null === $options ? pathinfo($path) : pathinfo($path, $options);
    foreach ($parts as $field => $value) {
        $parts[$field] = urldecode($value);
    }
    return $parts;
}
// calling
_pathinfo('すtest.jpg');
_pathinfo('すtest.jpg', PATHINFO_EXTENSION);

答案 5 :(得分:0)

private function _pathinfo($path, $options = null) {
  $result = pathinfo(' ' . $path, $options);
  return substr($result, 1);
}

答案 6 :(得分:0)

doc所示,

  

注意

     

pathinfo()可以识别语言环境,因此它可以解析包含以下内容的路径   多字节字符正确,必须使用以下命令设置匹配的语言环境   setlocale()函数。

和手册中的example