Использование iconv () для сохранения кодировки [duplicate]

14
задан Sabya 1 June 2010 в 08:30
поделиться

3 ответа

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

См. этот ответ .

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

D:\Users\Cataphract\Desktop\teste2>dir
 Volume in drive D is GRANDEDISCO
 Volume Serial Number is 945F-DB89

 Directory of D:\Users\Cataphract\Desktop\teste2

01-06-2010  17:16              .
01-06-2010  17:16              ..
01-06-2010  17:15                 0 coptic small letter shima follows ϭ.txt
01-06-2010  17:18                86 teste.php
               2 File(s)             86 bytes
               2 Dir(s)  12.178.505.728 bytes free

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

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

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

.
..
coptic small letter shima follows ?.txt
teste.php

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

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

>   php5ts_debug.dll!readdir_r(DIR * dp=0x02f94068, dirent * entry=0x00a7e7cc, dirent * * result=0x00a7e7c0)  Line 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)  Line 820 + 0x17 bytes   C
    php5ts_debug.dll!_php_stream_read(_php_stream * stream=0x02b94280, char * buf=0x02b9437c, unsigned int size=260, void * * * tsrm_ls=0x028a15c0)  Line 603 + 0x1c bytes  C
    php5ts_debug.dll!_php_stream_readdir(_php_stream * dirstream=0x02b94280, _php_stream_dirent * ent=0x02b9437c, void * * * tsrm_ls=0x028a15c0)  Line 1806 + 0x16 bytes    C
    php5ts_debug.dll!spl_filesystem_dir_read(_spl_filesystem_object * intern=0x02b94340, void * * * tsrm_ls=0x028a15c0)  Line 199 + 0x20 bytes  C
    php5ts_debug.dll!spl_filesystem_dir_open(_spl_filesystem_object * intern=0x02b94340, char * path=0x02b957f0, void * * * tsrm_ls=0x028a15c0)  Line 238 + 0xd bytes   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)  Line 645 + 0x11 bytes  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)  Line 658 + 0x1f bytes   C
    php5ts_debug.dll!zend_do_fcall_common_helper_SPEC(_zend_execute_data * execute_data=0x02bc0098, void * * * tsrm_ls=0x028a15c0)  Line 313 + 0x78 bytes   C
    php5ts_debug.dll!ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(_zend_execute_data * execute_data=0x02bc0098, void * * * tsrm_ls=0x028a15c0)  Line 423  C
    php5ts_debug.dll!execute(_zend_op_array * op_array=0x02b93888, void * * * tsrm_ls=0x028a15c0)  Line 104 + 0x11 bytes    C
    php5ts_debug.dll!zend_execute_scripts(int type=8, void * * * tsrm_ls=0x028a15c0, _zval_struct * * retval=0x00000000, int file_count=3, ...)  Line 1188 + 0x21 bytes C
    php5ts_debug.dll!php_execute_script(_zend_file_handle * primary_file=0x00a7fad4, void * * * tsrm_ls=0x028a15c0)  Line 2196 + 0x1b bytes C
    php.exe!main(int argc=2, char * * argv=0x028a14c0)  Line 1188 + 0x13 bytes  C
    php.exe!__tmainCRTStartup()  Line 555 + 0x19 bytes  C
    php.exe!mainCRTStartup()  Line 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 "coptic small letter shima follows ?.txt"
    cAlternateFileName: 0x02f941a0 "COPTIC~1.TXT"
dp->fileinfo.cFileName[34]
63 '?'

Да! Это символ # 63.

4
ответ дан Community 23 August 2018 в 16:46
поделиться
  • 1
    Разве он не может просто читать и писать имена как одиночные байты? – Álvaro González 1 June 2010 в 17:10
  • 2
    @ Álvaro G. Vicario Он мог, но у него не было бы имен собственных. NTFS поддерживает правильные имена файлов UCS-2, то, что вы описываете, является взломом. – Artefacto 1 June 2010 в 17:42
  • 3
    Ваше объяснение не могло быть лучше. Я многому научился сегодня :) – Álvaro González 1 June 2010 в 17:49
  • 4
    @Artefacto может ли он работать, добавив set utf-8 в .htaccess? или невозможно – Hana90 19 February 2018 в 23:01

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

$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
}
0
ответ дан Robijntje007 23 August 2018 в 16:46
поделиться

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

В 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 Подробнее об этой проблеме.

3
ответ дан Umberto Salsi 23 August 2018 в 16:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: