Преобразование кодировки в PHP (ISO-8859-1, UTF-8, CP1250)
Я хочу работать с данными из файла CSV, но понял, что буквы отображаются неправильно. Я пробовал миллион способов конвертировать кодировку, но ничего не работает. Работает на MacOS, PHP 7.4.4.
После выполнения fgets()
или fgetcsv()
для переменной дескриптора я получу это (например, 2 строки / строки).
Kód ADM;Kód obce;Název obce;Kód MOMC;Název MOMC;Kód MOP;Název MOP;Kód èásti obce;Název èásti obce;Kód ulice;Název ulice;Typ SO;Èíslo domovní;Èíslo orientaèní;Znak èísla orientaèního;PSÈ;Souøadnice Y;Souøadnice X;Platí Od
1234;1234;HorniDolni;;;;;1234;HorniDolni;;;è.p.;2;;;748790401;4799.98;15893971.21;2013-12-01T00:00:00
Это более-менее правильный чешский язык, но буква č
заменяется è
а также ř
заменяется ø
, ни один из них не является частью чешского алфавита. Уверен, неуместных букв в файле будет больше.
Выполнение file -I path/to/file
я получил file: text/plain; charset=iso-8859-1
что печально, потому что что касается вики, эта кодировка не включает чешский алфавит.
Ни одна из следующих команд не преобразовывала неуместные буквы:mb_convert_encoding($line, 'UTF-8', 'ISO8859-1')
iconv('ISO-8859-1', 'UTF-8', $line)
iconv('ISO8859-1', 'UTF-8', $line)
Я заметил, что в ISO-8859-1 КНИГУø
письмо имеет код 00F8
. Windows-1250 (который включает чешский аплабет) имеет правильную буквуř
с кодом 0159
но им обоим предшествует 00F8
. То же с письмомč
а также è
которым обоим предшествует код 00E7
. Я не очень хорошо разбираюсь в кодировке, но кажется, что файл закодирован в Windows-1250, но интерпретатор думает, что это кодировка ISO-8859-1, и берет букву, которая находится на месте / код оригинала.
Но ни одно преобразование (ISO-8859-1 => Windows-1250, ISO-8859-1 => UTF-8 или другое) не работает.
Кто-нибудь знает, как это решить? Спасибо!
1 ответ
Проблема с 8-битной кодировкой символов в том, что для интерпретации правильной кодовой страницы в основном требуется человеческий интеллект.
Когда ты бежишь file
в файле он может определить, что файл в основном состоит из печатаемых символов, но, поскольку он смотрит только на байты, он не может легко отличить iso-8895-1 от iso-8895-2. Чтобыfile
, 0x80
такой же как 0x80
.
file
может только сказать, что файл является текстовым и, вероятно, iso-8895-* или windows-*, из-за использования 0x80-0xFF
. Т.е. не только ASCII.
(Кодировки Unicode, такие как UTF-8 и UTF-16, легче обнаружить по их последовательности байтов или метке порядка байтов, установленной в верхней части файла)
Есть несколько интеллектуальных детекторов кодовых страниц символов, которые с помощью словарей на разных языках могут оценить кодовую страницу на основе последовательностей символов / байтов.
Вероятное преобразование, которое вам нужно, просто iso-8895-2 -> UTF-8
.
Для вас важно то, что вы знаете исходную кодировку (интерпретацию), а затем, когда вы ее проверяете, вы точно знаете, в какой кодировке вы ее просматриваете.
Например, PHP по умолчанию устанавливает кодировку HTTP на iso-8895-1
. Это означает, что вы вполне можете правильно конвертировать вiso-8895-2
, но ваш браузер будет "интерпретировать" как iso-8895-1
.
Лучший способ проверить - сохранить файл на диск, а затем использовать текстовый редактор, например VS Code, предварительно настроенный на требуемую кодировку, прежде чем открывать файл.
Если вам нужна дополнительная помощь, вам нужно будет отредактировать свой вопрос, включив в него точный код, который вы используете.