php readdir проблема с именем файла японского языка - PullRequest
4 голосов
/ 27 января 2009

У меня есть следующий код

<?php
if ($handle = opendir('C:/xampp/htdocs/movies')) {
    while (false !== ($file = readdir($handle))) {
        if ($file != "." && $file != "..") {
            echo $file."<br />\n";
        }
    }
    closedir($handle);
}
?>

Когда у него есть язык mb, такой как японский, он не отображается должным образом, а отображается как kyuukyoku Choujin R ????? ~? а не кьюкёку Choujin R 究 極 超人 あ ~ る

В любом случае, чтобы заставить его отображать правильное имя или сделать его доступным для загрузки другими?

Спасибо за помощь:)

Ответы [ 6 ]

9 голосов
/ 01 марта 2009

Я не могу говорить однозначно за PHP, но я подозреваю, что это та же самая основная проблема, что и с Python 2 (до того, как позже добавили специальную поддержку для строковых имен Unicode).

Я считаю, что PHP работает с именами файлов, используя стандартные функции open-et-al библиотеки C, которые основаны на байтах. В Windows (NT) они пытаются закодировать реальное имя файла Unicode, используя системную кодовую страницу. Это может быть cp1252 (аналогично ISO-8859-1) для западных машин или cp932 (аналог Shift-JIS) на японских машинах. Для любых символов, которых нет в системной кодовой странице, вы получите символ «?», И вы не сможете ссылаться на этот файл.

Чтобы обойти эту проблему, PHP должен будет сделать то же самое, что и Python 3.0, и начать использовать строки Unicode для имен файлов (и всего остального), используя функции _wopen'-et-al для получения доступа к именам файлов в формате Unicode. под виндой. Я ожидаю, что это произойдет в PHP6, но на данный момент вы, вероятно, в значительной степени напичканы. Вы можете изменить системную кодовую страницу на cp932, чтобы получить доступ к именам файлов, но вы все равно получите символы «?» Для любых других символов Юникода, не входящих в Shift-JIS, и в любом случае вы действительно не хотите, чтобы все внутренние строки вашего приложения были Shift-JIS, поскольку это довольно ужасная кодировка.

Если ваши собственные сценарии выбирают, как хранить файлы, я бы настоятельно рекомендовал использовать простые имена файлов на основе первичного ключа, такие как «4356», локально, помещая реальное имя файла в базу данных и передавая файлы с помощью переписывания / трейлинга. части пути в URL. Сохранение предоставленных пользователем имен файлов в ваших локальных именах файлов затруднительно, и это может стать причиной аварийных ситуаций в системе безопасности, даже не беспокоясь о Юникоде.

2 голосов
/ 29 января 2015

Как уже упоминалось @bobince, PHP возвращает имена файлов в указанной кодировке для Язык системы , который используется приложениями, не поддерживающими Юникод. Если символ не существует в текущей кодировке системы, имя файла будет содержать «?» вместо этого и не будет доступен.

Вы можете попробовать установить php-wfio.dll на https://github.com/kenjiuno/php-wfio, и обращаться к файлам по протоколу wfio://.

0 голосов
/ 01 марта 2009

извините:)

пытается это:

<?php if ($handle = opendir('C:/xampp/htdocs/movies')) { while (false !== ($file = readdir($handle))) { $filename_utf16 = iconv( "iso-8859-1", "utf-16", $file); if ($filename_utf16 != "." && $filename_utf16 != "..") { echo $filename_utf16 . "<br />\n"; } } closedir($handle); } ?>

0 голосов
/ 28 января 2009

Я думаю, что Windows использует UTF-16 для имен файлов. Поэтому попробуйте функцию mb_convert_encoding для преобразования внутренней кодировки в вашу выходную кодировку:

// convert from UTF-16 to UTF-8
echo mb_convert_encoding($file, 'UTF-8', 'UTF-16');

Возможно, вам сначала нужно изменить некоторые настройки (см. mb_get_info).

0 голосов
/ 27 января 2009

Вы пропустили две другие ссылки на переменную $ file , приятель, но это к лучшему, как мне кажется, я обнаружил чуть более эффективный метод; попробуйте:

<?php
if ($handle = opendir('C:/xampp/htdocs/movies')) {
    while (false !== ($file = readdir($handle))) {
        $file = mb_substr($file, mb_strrpos($file, '/') + 1);
        if ($file != "." && $file != "..") {
            echo $file . "<br />\n";
        }
    }
    closedir($handle);
}
?>
0 голосов
/ 27 января 2009

Замените любой экземпляр $ file на mb_substr ($ file, mb_strrpos ($ file, '/') + 1) , и все будет хорошо. Huzzah для многобайтовой кодировки!

...