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