У меня есть каталог, который содержит несколько файлов, многие из которых имеют неанглийское имя. Я использую PHP в Windows 7.
Я хочу перечислить имена файлов и их содержание, используя PHP.
В настоящее время я использую DirectoryIterator
а также file_get_contents
, Это работает для английских имен файлов, но не для неанглийских (китайских) имен файлов.
Например, у меня есть имена файлов, такие как «एक और प्रोब्लेम. Eml», «привет 鶨 鶖 鵨 鶣 鎹 em .eml».
DirectoryIterator
не может получить имя файла используя ->getFilename()
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 коптская маленькая буква Шима следует ϭ.txt 01-06-2010 17:18 86 teste.php 2 файл (ов) 86 байт 2 Dir (s) 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, беззнаковый размер int = 260, void * * * tsrm_ls = 0x028a15c0) Строка 603 + 0x1c байтов C php5ts_debug.dll! _php_stream_readdir (_php_stream * dirstream = 0x02b94280, _php_stream_dirent * ent = 0x02b9437c, пусто * * * 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 (интермедиат ХТ = 1, _zval_struct * return_value = 0x02b91f88, _zval_struct * * return_value_ptr = 0x00000000, _zval_struct * this_ptr = 0x02b92028, внутр return_value_used = 0, аннулируется * * * tsrm_ls = 0x028a15c0, длинное ctor_flags = 0) Строка 645 + 0x11 байт C php5ts_debug.dll! zim_spl_DirectoryIterator ___ конструкт (интермедиат ХТ = 1, _zval_struct * return_value = 0x02b91f88, _zval_struct * * return_value_ptr = 0x00000000, _zval_struct * this_ptr = 0x02b92028, внутр return_value_used = 0, аннулируются * * * 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, пусто * * * 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 = {...} ...} Атрибуты dwFile: 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 "следует коптская строчная буква shima? .txt" cAlternateFileName: 0x02f941a0 "COPTIC ~ 1.TXT" dp-> fileinfo.cFileName [34] 63 '?'
Да! Это персонаж № 63.
Краткий ответ:
В Windows вы не можете получить доступ к произвольным именам файлов с помощью PHP; Вы ограничены теми именами файлов, чье имя может быть представлено с выбранной в данный момент «кодовой страницей» (см. «Язык и региональные стандарты», панель «Формат» и вкладка «Административный» «Язык для программ, не поддерживающих Юникод»).
Более длинный ответ:
Windows использует UTF-16 для кодирования файлов начиная с Win2000, но PHP взаимодействует с базовой файловой системой как «не поддерживающая Юникод программа». Это означает, что существует текущая «таблица кодовых страниц», которая транслируется из строк 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
}