Сделайте PHP pathinfo () верните правильное имя файла, если имя файла UTF-8

При использовании 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] => ) 

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

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


 if (! function_exists ("mb_basename"))
 {
   функция mb_basename ($ path)
   {
     $ separator = "qq";
     $ path = preg_replace ("/ [^] / u", разделитель $. "\ $ 0". $ separator, $ path);
     $ base = basename ($ path);
     $ base = str_replace ($ separator, "", $ base);
     return $ base;
   }
 }
 if (! function_exists ("mb_pathinfo"))
 {
   функция mb_pathinfo ($ path, $ opt = "")
   {
     $ separator = "qq";
     $ path = preg_replace ("/ [^] / u", разделитель $. "\ $ 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;
   }
 }

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

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

перед использованием pathinfo

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

См. « Pathinfo () не может обрабатывать аргумент со специальными символами, такими как german 'Umlaute' ".

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