Заставьте PHP pathinfo () вернуть правильное имя файла, если имя файла UTF-8 - PullRequest
29 голосов
/ 15 декабря 2010

При использовании функции PHP pathinfo() для имени файла, известного как UTF-8, оно не возвращает правильное значение, если перед специальным символом нет «нормальных» символов.

Примеры:
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] => 
)  

Почему это происходит?Это касается всех акцентированных символов, которые я тестировал.

Ответы [ 6 ]

10 голосов
/ 13 февраля 2016

до использования pathinfo

setlocale(LC_ALL,'en_US.UTF-8');
pathinfo($OriginalName, PATHINFO_FILENAME);
pathinfo($OriginalName, PATHINFO_BASENAME);
10 голосов
/ 05 апреля 2013

Я использовал эти функции в PHP 5.3.3 - 5.3.18 для обработки проблемы UTF-8 в basename () и pathinfo ().


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;
  }
}
7 голосов
/ 16 декабря 2010

Временное решение этой проблемы заключается в том, чтобы убедиться, что перед акцентированными символами есть «нормальный» символ, например:

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(), кажется, работает, поэтому обходного пути там не требуется.

5 голосов
/ 15 декабря 2010
1 голос
/ 28 июля 2015

Когда обрабатываются символы 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);
0 голосов
/ 29 декабря 2016
private function _pathinfo($path, $options = null) {
  $result = pathinfo(' ' . $path, $options);
  return substr($result, 1);
}
...