Сделайте 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] =>
)
Почему он это делает? Это касается всех акцентированных символов, которые я тестировал.
Ответы
Ответ 1
Временная работа для этой проблемы заключается в том, чтобы убедиться, что перед акцентированными символами есть "нормальный" символ:
function getFilename($path)
{
// if there 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()
, похоже, работает, поэтому там не требуется обходной путь.
Ответ 2
Я использовал эти функции в 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;
}
}
Ответ 3
перед использованием pathinfo
setlocale(LC_ALL,'en_US.UTF-8');
pathinfo($OriginalName, PATHINFO_FILENAME);
pathinfo($OriginalName, PATHINFO_BASENAME);
Ответ 4
Обратитесь к разделу pathinfo() не может обрабатывать аргумент со специальными символами, такими как german 'Umlaute'.
Ответ 5
Когда обрабатываются 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);
Ответ 6
private function _pathinfo($path, $options = null) {
$result = pathinfo(' ' . $path, $options);
return substr($result, 1);
}