Проблема кодирования с помощью preg_replace () и scandir () - PullRequest
0 голосов
/ 15 марта 2010

В 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_ также. Но это было только хуже. Что я сделал не так?

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

Ответы [ 3 ]

1 голос
/ 15 марта 2010

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

0 голосов
/ 23 декабря 2015

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

Лучшее решение - выполнить команду 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.

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

for($k=6;$k<(count($array)-2);$k++) ...
0 голосов
/ 15 марта 2010

Вы пробовали 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
  }
?>
...