Подпись спецификации UTF-8 в файлах PHP
Я писал несколько классов PHP с комментариями и наткнулся на проблему. Мое имя (для тега @author) заканчивается символом ș
(который является символом UTF-8... и странным именем, я знаю).
Несмотря на то, что я сохраняю файл как UTF-8, некоторые друзья сообщили, что они видят, что этот символ полностью испорчен (È™
). Эта проблема устраняется путем добавления подписи спецификации. Но это меня немного беспокоит, так как я не так много знаю об этом, кроме того, что я видел в Википедии и на некоторых другие подобные вопросы здесь на SO.
Я знаю, что он добавляет некоторые вещи в начале файла, и из того, что я понял, это не так уж плохо, но я обеспокоен, потому что единственные проблемные сценарии, о которых я читал, связаны с файлами PHP. И поскольку я пишу классы PHP, чтобы делиться ими, быть совместимым на 100 % важнее, чем иметь мое имя в комментариях.
Но я пытаюсь понять последствия, должен ли я использовать его, не беспокоясь? или есть случаи, когда это может нанести ущерб? Когда?
7 answers
Действительно, спецификация - это фактические данные, отправленные в браузер. Браузер с радостью проигнорирует это, но тогда вы все равно не сможете отправлять заголовки.
Я считаю, что проблема действительно в настройках редактора вашего и вашего друга. Без спецификации редактор вашего друга может автоматически не распознать файл как UTF-8. Он может попытаться настроить свой редактор таким образом, чтобы редактор ожидал, что файл будет в UTF-8 (если вы используете реальную среду разработки, такую как NetBeans, то это даже можно сделать настройкой проекта, которую вы может передаваться вместе с кодом).
Альтернативой является попытка некоторых трюков: некоторые редакторы пытаются определить кодировку, используя некоторые эвристики, основанные на введенном тексте. Вы можете попробовать запустить каждый файл с помощью
<?php //Úτƒ-8 encoded
И, возможно, эвристика поймет это. Вероятно, там есть что-то получше, и вы можете либо поискать в Google, какие эвристики обнаружения кодирования распространены, либо просто попробовать:-)
В целом, я рекомендую просто исправить редактор настройки.
О, подождите, я неправильно понял последнюю часть: для распространения кода в любом месте, я думаю, вам безопаснее всего просто сделать так, чтобы все файлы содержали только младшие 7-битные символы, т. Е. обычный ASCII, или просто принять, что некоторые люди с древними редакторами видят, что ваше имя написано смешно. Нет надежного способа. Спецификация определенно плохая из-за уже отправленных заголовков. С другой стороны, пока вы добавляете только символы UTF-8 в комментарии и так далее, единственное влияние какого-либо редактора неправильное понимание кодировки - это странные символы. Я бы предпочел правильно написать ваше имя и добавить комментарий, ориентированный на эвристику, чтобы большинство редакторов его поняли, но всегда найдутся люди, которые вместо этого увидят поддельные символы.
Спецификация вызовет ошибку Headers already sent
, поэтому вы не можете использовать спецификацию в файлах PHP
Это старое сообщение, на которое уже был дан ответ, но я могу оставить вам некоторые другие ресурсы, которые я нашел, когда столкнулся с этой проблемой спецификации.
Http://people.w3.org/rishida/utils/bomtester/index.php на этой странице вы можете проверить, содержит ли конкретный файл спецификацию.
Существует также удобный скрипт, который выводит все файлы со спецификацией в вашем текущем каталоге.
<?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's 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 также помогает в этом, он дает вам возможность сохранить файл и не включать в него спецификацию
Это поздний ответ, но я все еще надеюсь, что это поможет. Пока
Просто чтобы вы знали, в 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
Или вы можете активировать буферизацию вывода в php.ini, что решит проблему "заголовки уже отправлены". Также очень важно использовать буферизацию вывода для повышения производительности, если ваш сайт имеет значительную нагрузку.
В PHP, в дополнение к ошибке "заголовки уже отправлены", наличие спецификации также может испортить HTML в браузере более тонкими способами.
Смотрите эту ссылку для описания проблемы.
Когда это происходит, в верхней части отображаемой страницы обычно не только остается заметное пространство, но если вы проверите HTML в Firefox или Chrome, вы можете заметить, что раздел "заголовок" пуст, а его элементы, как представляется, находятся в теле. Конечно, просмотр источника будет покажите все, где оно должно быть, но каким-то образом браузер интерпретирует это неправильно.
Спецификация на самом деле является наиболее эффективным способом идентификации файла UTF-8, и как современные браузеры, так и стандарты поддерживают и поощряют ее использование в телах HTTP-ответов.
В случае PHP-файлов это не файл, а сгенерированный вывод, который отправляется в качестве ответа, поэтому, очевидно, не стоит сохранять все PHP-файлы со спецификацией в начале, но это не значит, что вы не должны использовать спецификацию в своем ответе.
На самом деле вы можете безопасно ввести следующий код правильно перед объявлением типа документа (в случае, если вы генерируете HTML в качестве ответа):
<?="\xEF\xBB\xBF"?>
Для дальнейшего прочтения: https://www.w3.org/International/questions/qa-byte-order-mark#transcoding