как перебирать не-английские имена файлов в PHP

У меня есть каталог, который содержит несколько файлов, многие из которых имеют неанглийское имя. Я использую PHP в Windows 7.

Я хочу указать имя файла и его содержимое с помощью PHP.

В настоящее время я использую DirectoryIterator и file_get_contents . Это работает для имен файлов на английском языке, но не для имен, отличных от английского (китайского).

Например, у меня есть имена файлов, такие как «एक और प्रोब्लेम. Eml», «hello 鶨 鶖 鵨 鶣 鎹 鎣 .eml».

  1. DirectoryIterator не может получить имя файла, используя ->getFilename()
  2. file_get_contents также не удается открыть, даже если я жестко закодирую имя файла в его параметре.

Как мне это сделать?

Это невозможно. Это ограничение PHP. PHP использует многобайтовые версии Windows API; вы ограничены символами, которые может представлять ваша кодовая страница.

См. Этот ответ .

Содержание каталога:

 D: \ Users \ Катафракт \ Desktop \ teste2> реж
  Объем в диске D - GRANDEDISCO
  Объемный серийный номер - 945F-DB89

  Каталог D: \ Users \ Cataphract \ Desktop \ teste2

 01-06-2010 17:16.
 01-06-2010 17:16 ..
 01-06-2010 17:15 0 копия маленькой буквы shima следует за ϭ.txt
 01-06-2010 17:18 86 teste.php
                2 файлов (ов) 86 байт
                2 Дир (ов) 12.178.505.728 байт бесплатно

Содержимое тестового файла:

 <?php exec('pause'); foreach (new DirectoryIterator(".") as $v) { echo $v."\n"; } 

Результаты тестового файла:

 ,
 ..
 коптовая малая буква шима следует? .txt
 teste.php

Выход отладчика:

Стек вызова (PHP 5.3.0):

 > php5ts_debug.dll! readdir_r (DIR * dp = 0x02f94068, dirent * entry = 0x00a7e7cc, dirent * * result = 0x00a7e7c0) Строка 80 C
     php5ts_debug.dll! php_plain_files_dirstream_read (_php_stream * stream = 0x02b94280, char * buf = 0x02b9437c, unsigned int count = 260, void * * * tsrm_ls = 0x028a15c0) Строка 820 + 0x17 байт C
     php5ts_debug.dll! _php_stream_read (_php_stream * stream = 0x02b94280, char * buf = 0x02b9437c, unsigned int size = 260, void * * * tsrm_ls = 0x028a15c0) Строка 603 + 0x1c байтов C
     php5ts_debug.dll! _php_stream_readdir (_php_stream * dirstream = 0x02b94280, _php_stream_dirent * ent = 0x02b9437c, void * * * tsrm_ls = 0x028a15c0) Строка 1806 + 0x16 байт C
     php5ts_debug.dll! spl_filesystem_dir_read (_spl_filesystem_object * intern = 0x02b94340, void * * * tsrm_ls = 0x028a15c0) Строка 199 + 0x20 байт C
     php5ts_debug.dll! spl_filesystem_dir_open (_spl_filesystem_object * intern = 0x02b94340, char * path = 0x02b957f0, void * * * tsrm_ls = 0x028a15c0) Строка 238 + 0xd байт C
     php5ts_debug.dll! spl_filesystem_object_construct (int ht = 1, _zval_struct * return_value = 0x02b91f88, _zval_struct * * return_value_ptr = 0x00000000, _zval_struct * this_ptr = 0x02b92028, int return_value_used = 0, void * * * tsrm_ls = 0x028a15c0, long ctor_flags = 0) Строка 645 + 0x11 байт C
     php5ts_debug.dll! zim_spl_DirectoryIterator ___ construct (int ht = 1, _zval_struct * return_value = 0x02b91f88, _zval_struct * * return_value_ptr = 0x00000000, _zval_struct * this_ptr = 0x02b92028, int return_value_used = 0, void * * * tsrm_ls = 0x028a15c0) Строка 658 + 0x1f байт C
     php5ts_debug.dll! zend_do_fcall_common_helper_SPEC (_zend_execute_data * execute_data = 0x02bc0098, void * * * tsrm_ls = 0x028a15c0) Строка 313 + 0x78 байт C
     php5ts_debug.dll! ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (_zend_execute_data * execute_data = 0x02bc0098, void * * * tsrm_ls = 0x028a15c0) Строка 423 C
     php5ts_debug.dll! execute (_zend_op_array * op_array = 0x02b93888, void * * * tsrm_ls = 0x028a15c0) Строка 104 + 0x11 байт C
     php5ts_debug.dll! zend_execute_scripts (int type = 8, void * * * tsrm_ls = 0x028a15c0, _zval_struct * * retval = 0x00000000, int file_count = 3, ...) Строка 1188 + 0x21 байт C
     php5ts_debug.dll! php_execute_script (_zend_file_handle * primary_file = 0x00a7fad4, void * * * tsrm_ls = 0x028a15c0) Строка 2196 + 0x1b байт C
     php.exe! main (int argc = 2, char * * argv = 0x028a14c0) Строка 1188 + 0x13 байт C
     php.exe! __ tmainCRTStartup () Строка 555 + 0x19 байт C
     php.exe! mainCRTStartup () Строка 371 C

Это действительно знак вопроса?

 DP-> FileInfo
 {dwFileAttributes = 32 ftCreationTime = {...} ftLastAccessTime = {...} ...}
     dwFileAttributes: 32
     ftCreationTime: {dwLowDateTime = 2784934701 dwHighDateTime = 30081445}
     ftLastAccessTime: {dwLowDateTime = 2784934701 dwHighDateTime = 30081445}
     ftLastWriteTime: {dwLowDateTime = 2784934701 dwHighDateTime = 30081445}
     nFileSizeHigh: 0
     nFileSizeLow: 0
     dwReserved0: 3435973836
     dwReserved1: 3435973836
     cFileName: 0x02f9409c "Коптовая малая буква шима следует? .txt"
     cAlternateFileName: 0x02f941a0 "COPTIC ~ 1.TXT"
 DP-> fileinfo.cFileName [34]
 63 '?'

Да! Это персонаж № 63.

Короткий ответ:

В Windows вы не можете получить доступ к произвольным именам файлов с помощью PHP; вы ограничены именами файлов, чье имя может быть представлено с выбранной в данный момент «кодовой страницей» (см. раздел «Язык и региональные стандарты»), панель «Формат» и вкладка «Административный» «Язык для программ, отличных от Юникода»).

Более длинный ответ:

Windows использует UTF-16 для кодирования файлов с Win2000, но PHP связывается с базовой файловой системой как «программа, не поддерживающая Unicode». Это означает, что существует текущая «таблица кодовых страниц», которая транслируется из строк PHP в строки UTF-16 и наоборот. С PHP текущая страница кода может быть получена setlocale () в форме «language_country.codepage», например:

setlocale (LC_CTYPE, 0) ==> "english_United States.1252"

где 1252 – это таблица кодовых страниц Windows, выбранная в данный момент на панели управления; имена файлов, полученные из файловой системы, кодируются с использованием этой кодовой страницы; имена файлов, созданные с PHP, должны быть закодированы в соответствии с этой кодовой страницей. Все дело еще сложнее в том, что имена файлов UTF-16 транслируются в строки PHP, используя «наилучшую кодовую страницу», то есть приблизительное представление фактических символов / слов, поэтому вы не можете доверять именам файлов и путям извлекаются из файловой системы, поскольку они могут быть произвольно искалечены.

Рекомендации:

http://en.wikipedia.org/wiki/Windows_code_page Какие «кодовые страницы Windows».

https://bugs.php.net/bug.php?id=47096 Подробнее об этой проблеме.

Откройте файлы, которые у меня есть:

 $content = scandir($directory); $list = "<select size = 5 name ='file' id='file'>\n"; for($i = 0; $i < count ( $content ); $i ++) { $list .= "<option>$content[$i] </option>\n"; } $list .= "</select>\n"; 

Это будет успешно найти файл: 鶨 鶖 鵨 鶣 鎹 鎣 Я попробовал его здесь на дистрибутиве Linux, хотя ..

читать его вы используете: Строка за строкой:

 $lines = file('file.txt'); //loop through our array, show HTML source as HTML source; and line numbers too. foreach ($lines as $line_num => $line) { print "Line #<b>{$line_num}</b> : " . htmlspecialchars($line) . "<br />\n";//or try it without the htmlspecialchars }