Что такое «ANSI as UTF-8» и как я могу сделать fputcsv () генерировать UTF-8 с спецификацией?

Я создал PHP-скрипт, который генерирует CSV-файлы, которые ранее были сгенерированы другим процессом. И тогда CSV-файлы должны быть импортированы еще одним процессом.

Импорт старых файлов CSV отлично работает, но при импорте новых CSV-файлов возникают проблемы со специальными символами.

Когда я открываю старые CSV с помощью Notepad ++, он говорит, что кодировка UTF-8, и когда я открываю новые CSV с ней, он говорит, что их кодировка – это ANSI как UTF-8.

В чем разница между ними?

И как я могу сделать fopen и fputcsv использовать «чистый»? Кодировка UTF-8?

Благодаря!

В файле нет ничего плохого. «ANSI as UTF-8» означает, что нет спецификации, но Notepad ++ определенно идентифицировал кодировку как UTF-8, анализируя шаблоны байтов. Я проверил это, создав в нем файл с русским, греческим и польским текстами и сохраняя его как UTF-8 без спецификации. Вот:

# Russian Следующая # Greek Επόμενη # Polish Więcej 

Я сделал это в другом редакторе (EditPad Pro) и использовал шестнадцатеричный режим, чтобы убедиться, что спецификации там не было. Когда я открыл его в АЭС, он показал кодировку как «ANSI как UTF-8», и все символы отображались правильно. Затем, еще в шестнадцатеричном режиме, я удалил первый байт первого русского символа. Когда я снова открыл его на АЭС, он показал кодировку как «ANSI» и отобразил части текста, не содержащие ASCII, как mojibake :

 ; Russian ¡Ð»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ ; Greek Επόμενη ; Polish WiÄ™cej 

Вернемся к EditPad, и на этот раз я добавил спецификацию, но не отредактировал кириллицу. На этот раз АЭС сообщила, что кодировка «UTF-8» и все отображаются правильно, за исключением первого русского символа, как показано ниже. «A1» – это шестнадцатеричное представление того, что должно было быть вторым байтом этого символа в UTF-8. Он отобразился в инвертированной цветовой схеме, чтобы указать на ошибку.

 # Russian A1ледующая # Greek Επόμενη # Polish Więcej 

Подводя итог: В отсутствие спецификации, Notepad ++ ищет байты, которые не могут представлять символы ASCII, потому что их значения больше 127 (или 7F hex). Если он находит что-либо, но все они соответствуют шаблонам, требуемым UTF-8 , он декодирует файл как UTF-8 и сообщает кодировку в строке состояния как «ANSI as UTF-8».

Но если он найдет хотя бы один байт, который не соответствует UTF-8, он декодирует файл как «ANSI», что означает однобайтную кодировку по умолчанию для базовой платформы. Если ваш файл был поврежден, это то, что вы увидите.

EDIT: Несмотря на то, что ваш файл действителен без него, вы можете добавить спецификацию вручную, записав три байта "EF BB BF" в самом начале файла, но должен быть лучший способ. Как вы создаете контент сейчас? Потому что это UTF-8, где-то есть, по крайней мере, один не-ASCII-символ; в противном случае АЭС сообщит об этом как «ANSI».

Другая возможность рассмотреть: если вы имеете какое-либо влияние на процесс, который потребляет ваш CSV-файл, возможно, вы можете настроить его на ожидание UTF-8 без спецификации. Технически любое программное обеспечение, которое может декодировать UTF-8 с помощью спецификации, но не без нее, нарушено. Консорциум Unicode фактически не поощряет использование спецификации UTF-8, а не то, что кто-то слушает.

Согласно связанным с Notepad ++ потокам здесь и здесь «ANSI как UTF-8» указывает UTF-8 без спецификации, в то время как простой «UTF-8» означает UTF-8 с спецификацией. Поэтому, возможно, для процесса чтения CSV требуется знак байтового порядка, чтобы правильно считать CSV как UTF-8.

Но прежде чем вдаваться в это, убедитесь, что ваш скрипт действительно пишет UTF-8! Когда вы открываете новые CSV-файлы в Notepad ++ (и это говорит «ANSI как UTF-8»), отображаются ли все «специальные» символы? Если нет, вам нужно адаптировать свой скрипт для написания UTF-8, если да, проверьте разницу BOM.

Попробуйте изменить свой PHP-скрипт на UTF-8. Иногда необходимо (несмотря на то, что это можно обойти), чтобы иметь скрипт в той же кодировке символов.

Аналогичная проблема: PHP: Explode с использованием специальных символов

Стоит отметить, что ANSI как UTF-8, то есть UTF-8 без спецификации, полезна, если вы форматируете свои PHP-файлы как UTF-8. Если ваш PHP-файл выводит html в браузер, то спецификация включена в вывод HTML, который валидатор w3c явно предупреждает:

Байт-порядок отмечен в файле UTF-8.

Известно, что символ кодировки байтов Юникода (BOM) в кодированных файлах UTF-8 вызывает проблемы для некоторых текстовых редакторов и старых браузеров. Вы можете захотеть избежать его использования до тех пор, пока он не будет лучше поддержан.

В дополнение к этому, я заметил, что BOM смущает Firebug Firefox, который теперь считает, что весь ваш <head> контент находится в <body> .