Подпись спецификации UTF-8 в файлах PHP - PullRequest
22 голосов
/ 01 апреля 2010

Я писал несколько прокомментированных классов PHP и наткнулся на проблему. Мое имя (для тега @author) заканчивается ș (который является символом UTF-8, ... и странным именем, я знаю).

Несмотря на то, что я сохраняю файл как UTF-8, некоторые друзья сообщили, что они видят, что этот персонаж полностью испорчен (È™). Эта проблема устраняется путем добавления подписи спецификации. Но эта вещь немного беспокоит меня, так как я мало что знаю об этом, за исключением того, что я видел в Википедии и по некоторым другим подобным вопросам здесь, на SO.

Я знаю, что он добавляет некоторые вещи в начало файла, и из того, что я понял, это не так уж и плохо, но я обеспокоен, потому что единственные проблемные сценарии, которые я читаю, касаются задействованных файлов PHP. И поскольку я пишу PHP-классы, чтобы делиться ими, 100% -ная совместимость важнее, чем мое имя в комментариях.

Но я пытаюсь понять последствия, я должен использовать это, не беспокоясь? или есть случаи, когда это может привести к повреждению? Когда?

Ответы [ 7 ]

24 голосов
/ 01 апреля 2010

Действительно, спецификация - это фактические данные, отправляемые в браузер. Браузер с радостью проигнорирует его, но вы все равно не сможете отправлять заголовки.

Я считаю, что проблема действительно в настройках редактора для вас и вашего друга. Без спецификации редактор вашего друга не сможет автоматически распознать файл как UTF-8. Он может попытаться настроить свой редактор так, чтобы редактор ожидал, что файл будет в UTF-8 (если вы используете настоящую IDE, такую ​​как NetBeans, тогда это может быть даже сделано настройкой проекта, которую вы можете перевод вместе с кодом).

Альтернатива состоит в том, чтобы попробовать некоторые хитрости: некоторые редакторы пытаются определить кодировку, используя некоторую эвристику на основе введенного текста. Вы можете попробовать запустить каждый файл с

<?php //Úτƒ-8 encoded

и, возможно, эвристик получит это. Возможно, там есть что-то лучшее, и вы можете либо узнать, какой тип эвристики обнаружения кодирования является распространенным, либо просто попробовать Google: -)

В общем, я рекомендую просто исправить настройки редактора.

Ой, подождите, я неправильно прочитал последнюю часть: для распространения кода куда-либо, я думаю, вам лучше всего просто сделать так, чтобы все файлы содержали только младшие 7-битные символы, то есть просто ASCII, или просто принимали, что некоторые люди с древние редакторы видят ваше имя написанным смешно. Не существует надежного способа. Спецификация определенно плохая из-за уже отправленных заголовков. С другой стороны, до тех пор, пока в комментарии добавляются только символы UTF-8, единственное влияние неправильного понимания кодировкой редактора - странные символы. Я бы правильно назвал ваше имя и добавил комментарий, ориентированный на эвристику, чтобы большинство редакторов получало его, но всегда найдутся люди, которые вместо этого увидят поддельные символы.

13 голосов
/ 01 апреля 2010

BOM приведет к ошибке Headers already sent, поэтому вы не можете использовать BOM в файлах PHP

9 голосов
/ 03 февраля 2011

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

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 также помогает в этом, он дает вам возможность сохранить файл и не включать содержимое спецификации

Это поздний ответ, но я все еще надеюсь, что это поможет. Bye

7 голосов
/ 25 марта 2011

Как вы знаете, в 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
2 голосов
/ 05 января 2012

В PHP, в дополнение к ошибке «заголовки уже отправлены», наличие спецификации может также испортить HTML-код в браузере.

См. Эту ссылку для описания проблемы.

Когда это происходит, не только обычно есть заметное пространство вверху отображаемой страницы, но если вы просматриваете HTML в Firefox или Chrome, вы можете заметить, что раздел заголовка пуст, а его элементы выглядят как тело. Конечно, просмотр исходного кода покажет все, где он должен быть, но браузер как-то неправильно его интерпретирует.

2 голосов
/ 01 апреля 2010

Или вы можете активировать буферизацию вывода в php.ini, что решит проблему «заголовки уже отправлены». Также очень важно использовать выходную буферизацию для повышения производительности, если ваш сайт имеет значительную нагрузку.

1 голос
/ 08 ноября 2016

Спецификация на самом деле является наиболее эффективным способом идентификации файла UTF-8, и как современные браузеры, так и стандарты поддерживают и поощряют его использование в телах ответа HTTP.

В случае файлов PHP это не файл, а сгенерированный вывод, который отправляется в качестве ответа, поэтому очевидно, что не стоит сохранять все файлы PHP с помощью спецификации в начале, но это не означает, что вам не следует используйте спецификацию в своем ответе.

На самом деле вы можете безопасно ввести следующий код прямо перед объявлением doctype (если вы генерируете HTML в качестве ответа):

<?="\xEF\xBB\xBF"?>

Для дальнейшего чтения: https://www.w3.org/International/questions/qa-byte-order-mark#transcoding

...