web-dev-qa-db-ja.com

PHPファイル内のUTF-8 BOM署名

私はいくつかのコメント付きのPHP=クラスを書いていて、問題に遭遇しました。(@ authorタグの)私の名前はș(UTF-8文字です)で終わります。 ...そして奇妙な名前は知っています)。

ファイルをUTF-8として保存しても、一部の友人から、その文字が完全にめちゃくちゃになっているとの報告がありました(È™)。この問題は、BOM署名を追加することで解消されます。しかし、ウィキペディアで見たものや、SOに関する他のいくつかの同様の質問を除いて、私はそれについてあまり知らないので、それは私を少し困らせます。

私はそれがファイルの最初にいくつかのことを追加することを知っています、そして私が理解したことからそれは悪くはありませんが、私が関係した唯一の問題のあるシナリオが関連するPHPファイル。そして、私はPHPそれらを共有するためのクラスを書いているので、100%互換であることは、コメントに私の名前を含めることよりも重要です。

しかし、私はその意味を理解しようとしていますが、心配せずにそれを使用すべきですか?それとも損傷の原因となる場合がありますか?いつ?

23
treznik

実際、BOMはブラウザに送信される実際のデータです。ブラウザはそれを喜んで無視しますが、それでもヘッダーを送信することはできません。

問題は本当にあなたとあなたの友人のエディタ設定にあると思います。 BOMがないと、友達の編集者がファイルをUTF-8として自動的に認識しない可能性があります。彼は、エディタexpectsファイルがUTF-8になるようにエディタを設定しようとすることができます(NetBeansなどの実際のIDEを使用する場合、これはコードと一緒に転送できるプロジェクト設定にすることもできます)。

代替策は、いくつかのトリックを試すことです:一部のエディターは、入力されたテキストに基づいて、いくつかのヒューリスティックを使用してエンコーディングを決定しようとします。あなたは各ファイルを

<?php //Úτƒ-8 encoded

そして多分ヒューリスティックはそれを得るでしょう。おそらくもっと良いものがそこにあります、そしてあなたは一般的にどのような種類のエンコーディング検出ヒューリスティックスが一般的であるかについてグーグルすることができます、あるいは単に試してみてください:-)

全体として、エディターの設定を修正することをお勧めします。

ああ待って、私は最後の部分を読み違えました:コードをどこにでも拡散するには、すべてのファイルに下位7ビット文字(つまりプレーンASCII)のみを含めるか、古代のエディターの一部の人々が見ることを受け入れるだけの方が安全だと思いますおかしいと書いたあなたの名前。フェイルセーフな方法はありません。ヘッダーはすでに送信されているため、BOMは間違いなく悪いものです。反対に、コメントにUTF-8文字のみを入れる限り、エンコーディングを誤解している一部のエディターの唯一の影響は、奇妙な文字です。私はあなたの名前を正しくつづり、ヒューリスティックスを対象としたコメントを追加して、ほとんどの編集者が理解できるようにしますが、代わりに偽の文字が表示される人が常にいます。

25
skrebbel

BOMはHeaders already sentエラーなので、PHPファイルではBOMを使用できません。

14

これは古い投稿であり、既に回答済みですが、このBOMの問題に直面したときに見つけた他のリソースをいくつか残すことができます。

http://people.w3.org/rishida/utils/bomtester/index.php このページでは、特定のファイルにBOMが含まれているかどうかを確認できます。

現在のディレクトリにBOMを含むすべてのファイルを出力する便利なスクリプトもあります。

<?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もこれを支援し、ファイルを保存してBOMを含めないようにするオプションを提供します

その遅い答えですが、私はそれが役に立てば幸いです。さようなら

9
omabena

ご存知のように、phpにはzend.multibyteというオプションがあります。これにより、phpはHeaders already sentエラーを出さずにBOMでファイルを読み取ることができます。

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
7
solarc

PHPでは、「ヘッダーはすでに送信されました」エラーに加えて、BOMの存在により、ブラウザーのHTMLがさらに微妙に混乱する可能性があります。

問題の概要については、この link を参照してください。

これが発生すると、通常、レンダリングされたページの上部に目立つスペースがあるだけでなく、FirefoxまたはChromeでHTMLを検査すると、ヘッドセクションが空で、その要素が本文にあるように見えることがあります。もちろん、ソースを表示すると、本来あるべき場所がすべて表示されますが、どういうわけかブラウザはそれを間違って解釈しています。

2
matthewv789

または、php.iniで出力バッファリングをアクティブにして、「すでに送信されたヘッダー」の問題を解決することもできます。サイトの負荷が大きい場合は、パフォーマンスのために出力バッファリングを使用することも非常に重要です。

2
peufeu

BOMは実際にはUTF-8ファイルを識別する最も効率的な方法であり、最新のブラウザーと標準の両方がHTTP応答本文での使用をサポートおよび推奨しています。

PHPファイルの場合、ファイルではなく生成された出力が応答として送信されるため、すべてのPHPファイルを最初はBOMですが、応答でBOMを使用すべきではないという意味ではありません。

実際には、Doctype宣言の直前に次のコードを安全に挿入できます(応答としてHTMLを生成している場合)。

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

詳しくは https://www.w3.org/International/questions/qa-byte-order-mark#transcoding

1
Szabolcs Páll