Подпись UTF-8 BOM в файлах PHP
Я писал некоторые комментируемые классы PHP, и я наткнулся на проблему. Мое имя (для тега @author) заканчивается символом ș
(который является символом UTF-8... и странным именем, я знаю).
Несмотря на то, что я сохраняю файл как UTF-8, некоторые друзья сообщили, что они видят, что персонаж полностью перепутался (È™
). Эта проблема уходит, добавляя подпись спецификации. Но эта вещь немного меня беспокоит, так как я не знаю об этом много, кроме того, что я видел в Википедии, и о некоторых других подобных вопросах здесь, на SO.
Я знаю, что он добавляет некоторые вещи в начале файла, и из того, что я понял, это не так уж плохо, но я обеспокоен тем, что только в некоторых проблемных сценариях, которые я читал, были задействованы файлы PHP. И поскольку я пишу классы PHP для их совместного использования, то на 100% совместимость важнее, чем мое имя в комментариях.
Но я пытаюсь понять последствия, следует ли использовать его, не беспокоясь? или есть случаи, когда это может нанести ущерб? Когда?
Ответы
Ответ 1
Действительно, спецификация - это фактические данные, отправленные в браузер. Браузер будет с радостью игнорировать его, но вы все равно не можете отправлять заголовки.
Я считаю, что проблема действительно в ваших настройках редактора и вашего друга. Без спецификации, ваш редактор друзей не может автоматически распознавать файл как UTF-8. Он может попытаться настроить свой редактор таким образом, что редактор ожидает, что файл будет находиться в UTF-8 (если вы используете реальную среду IDE, такую как NetBeans, тогда это может быть даже сделана настройка проекта, которую вы можете перенести вместе с кодом).
Альтернатива - попробовать некоторые трюки: некоторые редакторы пытаются определить кодировку, используя некоторую эвристику на основе введенного текста. Вы можете попробовать запустить каждый файл с помощью
<?php //Úτƒ-8 encoded
и, возможно, эвристика получит его. Там, вероятно, лучше всего добавить туда, и вы можете либо google, для каких эвристик обнаружения кодирования, или просто попробовать: -)
В целом, я рекомендую только установить настройки редактора.
Ой, подождите, я неправильно прочитал последнюю часть: для распространения кода в любом месте, я думаю, вы безопаснее всего, чтобы все файлы содержали только более низкие 7-битные символы, то есть простой ASCII, или просто принять, что некоторые люди с древние редакторы видят, что ваше имя написано смешно. Нет отказоустойчивого пути. Спецификация определенно плоха из-за уже отправленных заголовков. С другой стороны, до тех пор, пока вы добавляете только символы UTF-8 в комментарии, и поэтому единственное влияние некоторых редакторов на непонимание кодировки - это странные символы. Я бы поступил правильно для написания вашего имени и добавления комментария, ориентированного на эвристику, чтобы большинство редакторов его получили, но всегда будут люди, которые будут видеть фиктивные символы.
Ответ 2
BOM вызывает ошибку Headers already sent
, поэтому вы не можете использовать спецификацию в файлах PHP
Ответ 3
Это старый пост и уже был дан ответ, но я могу оставить вам некоторые другие ресурсы, которые я нашел, когда столкнулся с этой проблемой спецификации.
http://people.w3.org/rishida/utils/bomtester/index.php с этой страницей вы можете проверить, содержит ли конкретный файл спецификацию.
Существует также удобный script, который выводит все файлы с спецификацией в ваш текущий каталог.
<?php
function fopen_utf8 ($filename) {
$file = @fopen($filename, "r");
$bom = fread($file, 3);
if ($bom != b"\xEF\xBB\xBF")
{
return false;
}
else
{
return true;
}
}
function file_array($path, $exclude = ".|..|design", $recursive = true) {
$path = rtrim($path, "/") . "/";
$folder_handle = opendir($path);
$exclude_array = explode("|", $exclude);
$result = array();
while(false !== ($filename = readdir($folder_handle))) {
if(!in_array(strtolower($filename), $exclude_array)) {
if(is_dir($path . $filename . "/")) {
// Need to include full "path" or it an infinite loop
if($recursive) $result[] = file_array($path . $filename . "/", $exclude, true);
} else {
if ( fopen_utf8($path . $filename) )
{
//$result[] = $filename;
echo ($path . $filename . "<br>");
}
}
}
}
return $result;
}
$files = file_array(".");
?>
Я обнаружил, что код на php.net
Dreamweaver также помогает в этом, он дает вам возможность сохранить файл и не включать материал спецификации
Его поздний ответ, но я все еще надеюсь, что это поможет.
Bye
Ответ 4
Просто, чтобы вы знали, есть опция в php, zend.multibyte
, которая позволяет php читать файлы с спецификацией без предоставления ошибки Headers already sent
.
Из файла php.ini:
; If enabled, scripts may be written in encodings that are incompatible with
; the scanner. CP936, Big5, CP949 and Shift_JIS are the examples of such
; encodings. To use this feature, mbstring extension must be enabled.
; Default: Off
;zend.multibyte = Off
Ответ 5
В PHP, в дополнение к ошибке "отправленные заголовки", наличие спецификации может также испортить HTML в браузере более тонкими способами.
См. ссылку для контура проблемы.
Когда это происходит, не только обычно находится заметное место в верхней части страницы, но, если вы проверяете HTML в Firefox или Chrome, вы можете заметить, что раздел главы пуст, и его элементы, как представляется, находятся в тело. Конечно, источник просмотра покажет все, где это должно быть, но почему-то браузер интерпретирует это неправильно.
Ответ 6
Или вы можете активировать буферизацию вывода в php.ini, которая решит проблему с "заголовками, уже отправленными". Также очень важно использовать буферизацию вывода для производительности, если ваш сайт имеет значительную нагрузку.
Ответ 7
BOM - фактически самый эффективный способ идентификации файла UTF-8, а также поддержка современных браузеров и стандартов и поощрение использования его в телах ответа HTTP.
В случае файлов PHP это не файл, а сгенерированный вывод, который отправляется как ответ, поэтому, очевидно, не рекомендуется сохранять все файлы PHP с помощью спецификации в начале, но это не значит, что вы не должны используйте спецификацию в своем ответе.
Фактически вы можете безопасно ввести следующий код прямо перед объявлением doctype (если вы генерируете HTML как ответ):
<?="\xEF\xBB\xBF"?>
Для дальнейшего чтения: https://www.w3.org/International/info/qa-byte-order-mark#transcoding