Вопрос

В OS-X (PHP5.2.11) у меня есть файл:siësta.doc (и тысячи других с именами файлов в Юникоде), и я хочу преобразовать имена файлов в формат, доступный для использования в Интернете (a-zA-Z0-9.).Если я жестко закодирую указанное выше имя файла, я смогу выполнить правильное преобразование:

<?php
  $file = 'siësta.doc';
  echo preg_replace("/[^a-zA-Z0-9.]/u", '_', $file);
  // Output: si_sta.doc
?>

Но если я прочитаю имена файлов с помощью scandir, у меня получатся странные преобразования:

<?php
  $files = scandir(DIRNAME);
  foreach ($files as $file) {
    echo preg_replace("/[^a-zA-Z0-9.]/u", '_', $file);
    // Output for the file above: sie_sta.doc
  }
?>

Я попытался определить кодировку, установить кодировку, преобразовать ее с помощью функций iconv.Я также попробовал функции mb_.Но это было только хуже.Что я сделал не так?

Заранее спасибо

Это было полезно?

Решение

Интересно.После небольшой проверки я обнаружил, что OSX хранит имена файлов как "разложенный юникод" (см. http://developer.apple.com/mac/library/qa/qa2001/qa1173.html).То есть "'" представлено как "e" + символ диареи (0xcc88).

Другие советы

Вы пробовали utf8_encode?(Работает, по крайней мере, в Windows)

<?php
  $files = scandir(DIRNAME);
  foreach ($files as $file) {
    echo preg_replace("/[^a-zA-Z0-9.]/u", '_', utf8_encode($file));
    // Output for the file above: sie_sta.doc
  }
?>

Проблема заключается в связи между Windows и php.Невозможно получить имена файлов в юникоде, поскольку они зависят от языка приложения Windows, отличного от юникода.

Лучшее решение - выполнить команду dir и получить информацию для обработки, но вы должны сделать это с помощью cmd и получить короткие имена Windows:

chcp 65001
dir /x c:\test\ > myinfo.txt

Он возвращается:

 El volumen de la unidad C es Windows8_OS
 El número de serie del volumen es: 14A3-025F

 Directorio de C:\test

22/12/2015  22:11    <DIR>                       .
22/12/2015  22:11    <DIR>                       ..
22/12/2015  22:12                 0              a.txt
22/12/2015  22:10    <DIR>                       English
22/12/2015  22:10    <DIR>          ESPAOL~1     Español
22/12/2015  22:11    <DIR>          8311~1       ру́сский язы́к
22/12/2015  22:10    <DIR>          _0B41~1      عربي ,عربى
22/12/2015  22:10    <DIR>          8F4C~1       北方話
               1 archivos              0 bytes
               7 dirs  839.672.786.944 bytes libres

Затем вы можете прочитать myinfo.txt чтобы получить связь между оригинальным именем и кратким именем Windows.

Некоторые функции PHP прекрасно работают с короткими именами, и вы можете создавать и массивировать их так, как если бы вам нужно было их отобразить:

$array['short_name']= $original_name;

Например: is_dir, is_file работает нормально.Однако, scandir или is_readable терпит неудачу и с короткими именами.Решение для использования этих функций заключается в рекурсивном повторном запуске команды dir.

Чтобы получить информацию из текстового файла, вы можете использовать регулярное выражение или substr, отбросив первые пять строк и последние две.Например:

for($k=6;$k<(count($array)-2);$k++) ...
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top