2013-03-15 2 views
0

Мне нужно преобразовать загруженные имена файлов с неизвестной кодировкой в ​​Windows-1252, одновременно сохраняя совместимость с UTF-8.Преобразование кодирования PHP в Windows-1252 при сохранении совместимости UTF-8

Поскольку я передаю эти файлы контроллеру (на который я не влияю), файлы должны быть закодированы в Windows-1252. Затем этот контроллер генерирует список допустимых файлов (имен), которые хранятся через MySQL в базе данных, поэтому мне нужна совместимость с UTF-8. Имена файлов, переданные контроллеру, и имена файлов, записанные в базу данных, ДОЛЖНЫ совпадать. Все идет нормально.

В некоторых редких случаях при преобразовании в «Windows-1252» (например, с символом te «ï») символ преобразуется в нечто недопустимое в UTF-8. Затем MySQL удаляет эти недопустимые символы - в результате имена файлов на диске и имена файлов, хранящиеся в базе данных, больше не совпадают. Это преобразование, который failes иногда, достигаются с помощью простой перекодировки:

$sEncoding  = mb_detect_encoding($sOriginalFilename); 
$sTargetFilename = iconv($sEncoding, "Windows-1252//IGNORE", $sOriginalFilename); 

Для предотвращения недопустимых символов, генерируемых преобразования, я снова могу удалить все недействительные UTF-8 символов из перекодировано строки:

ini_set('mbstring.substitute_character', "none"); 
$sEncoding  = mb_detect_encoding($sOriginalFilename); 
$sTargetFilename = iconv($sEncoding, "Windows-1252//TRANSLIT", $sOriginalFilename); 
$sTargetFilename = mb_convert_encoding($sTargetFilename, 'UTF-8', 'Windows-1252'); 

Но это полностью удалит/перекодирует любые специальные символы, оставшиеся в строке. Например, я теряю все «äöüÄÖÜ» и т. Д., Которые довольно регулярны на немецком языке.

Если вы знаете более чистый и простой способ кодирования для Windows-1252 (без потери действительных специальных символов), сообщите мне.

Любая помощь очень ценится. Заранее спасибо!

ответ

1

Я думаю, что проблема с манией заключается в том, что mb_detect_encoding() не делает точно, что вы думаете. Он пытается обнаружить кодировку символов, но делает это из довольно ограниченного списка предопределенных кодировок. По умолчанию эти кодировки возвращаются mb_detect_order(). В моем компьютере они:

  • ASCII
  • UTF-8

Так эта функция совершенно бесполезна, если не заботиться о составлении списка кандидатов кодировок и подкормки функцию с ним.

Кроме того, в принципе нет надежного способа угадать кодировку произвольной входной строки, даже если вы ограничиваете себя небольшим подмножеством кодировок. В вашем случае Windows-1252 находится так близко от ISO-8859-1 и ISO-8859-15, что у вас нет способа рассказать им обособленно, кроме визуального осмотра ключевых символов, таких как & curren; или €.

2

Вы не можете иметь строку Windows-1252 и UTF-8 одновременно. Наборы символов идентичны для первых 128 символов (они содержат, например, базовый латинский алфавит), но когда он выходит за рамки (например, для Umlauts), он либо один, либо другой. У них разные коды в UTF-8, чем в Windows-1252.

1

Сохраните ASCII в файловой системе - если вам нужно поддерживать символы вне ASCII в имени файла, есть схемы , которые вы можете использовать для представления символов Unicode, сохраняя при этом ASCII.

Например, процент кодирования:

< äöüÄÖÜ.txt ->%C3%A4%C3%B6%C3%BC%C3%84%C3%96%C3%9C.txt

Конечно, это ударит предел имя файла довольно быстро и не очень оптимальным.

Как насчет punycode?

äöüÄÖÜ.txt < ->xn--4caa7cb2ac.txt