35

在已知为 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] => 
)  

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

4

7 回答 7

17

使用前 pathinfo

setlocale(LC_ALL,'en_US.UTF-8');
pathinfo($OriginalName, PATHINFO_FILENAME);
pathinfo($OriginalName, PATHINFO_BASENAME);
于 2016-02-13T16:56:51.047 回答
10

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

if (!function_exists("mb_basename"))
{
  函数 mb_basename($path)
  {
    $分隔符 = "qq";
    $path = preg_replace("/[^ ]/u", $separator."\$0".$separator, $path);
    $base = basename($path);
    $base = str_replace($separator, "", $base);
    返回 $base;
  }
}
if (!function_exists("mb_pathinfo"))
{
  函数 mb_pathinfo($path, $opt = "")
  {
    $分隔符 = "qq";
    $path = preg_replace("/[^ ]/u", $separator."\$0".$separator, $path);
    if ($opt == "") $pathinfo = pathinfo($path);
    否则 $pathinfo = pathinfo($path, $opt);

    if (is_array($pathinfo))
    {
      $路径信息2 = $路径信息;
      foreach($pathinfo2 as $key => $val)
      {
        $pathinfo[$key] = str_replace($separator, "", $val);
      }
    }
    否则 if (is_string($pathinfo)) $pathinfo = str_replace($separator, "", $pathinfo);
    返回$路径信息;
  }
}
于 2013-04-05T06:46:13.830 回答
8

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

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部分pathinfo()似乎确实有效,因此不需要解决方法。

于 2010-12-16T09:33:48.913 回答
5

请参阅“ pathinfo() 无法处理带有特殊字符(如德语 'Umlaute' )的参数”。

于 2010-12-15T15:52:59.927 回答
1

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

基于此注释,我们将输入转换(编码)为 ansi 字符,然后仍然使用函数 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);
于 2015-07-28T09:01:12.290 回答
0
private function _pathinfo($path, $options = null) {
  $result = pathinfo(' ' . $path, $options);
  return substr($result, 1);
}
于 2016-12-29T11:15:33.680 回答
0

正如文档所示,

警告

pathinfo() 是区域设置感知的,因此要正确解析包含多字节字符的路径,必须使用 setlocale() 函数设置匹配的区域设置。

和手册中的例子

于 2019-08-10T03:34:28.903 回答