У меня есть каталог, который содержит несколько файлов, многие из которых имеют неанглийское имя. Я использую PHP в Windows 7.
Я хочу указать имя файла и его содержимое с помощью PHP.
В настоящее время я использую DirectoryIterator
и file_get_contents
. Это работает для имен файлов на английском языке, но не для имен, отличных от английского (китайского).
Например, у меня есть имена файлов, такие как «एक और प्रोब्लेम. Eml», «hello 鶨 鶖 鵨 鶣 鎹 鎣 .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 копия маленькой буквы 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 }