ホームページ >バックエンド開発 >PHPチュートリアル >utf-8 と BOM なしの utf-8 の違い

utf-8 と BOM なしの utf-8 の違い

WBOY
WBOYオリジナル
2016-08-08 09:20:381368ブラウズ

BOM——バイトオーダーマークであるByte Order Mark

UCSエンコードには「ZERO WIDTH NO-BREAK SPACE」という文字があり、そのエンコードはFEFFです。 FFFE は UCS には存在しない文字ですので、実際の送信では出現しないはずです。 UCS 仕様では、バイト ストリームを送信する前に文字「ZERO WIDTH NO-BREAK SPACE」を送信することを推奨しています。このように、受信機が FEFF を受信した場合は、バイト ストリームがビッグ エンディアンであることを示し、FFFE を受信した場合は、バイト ストリームがリトル エンディアンであることを示します。したがって、「ZERO WIDTH NO-BREAK SPACE」という文字は BOM とも呼ばれます。

UTF-8 はバイト順序を示すために BOM を必要としませんが、BOM を使用してエンコード方式を示すことができます。文字「ZERO WIDTH NO-BREAK SPACE」の UTF-8 エンコーディングは EF BB BF です。したがって、受信側が EF BB BF で始まるバイト ストリームを受信すると、それが UTF-8 でエンコードされていることを認識します。

UTF-8 でエンコードされたファイルでは、BOM は 3 バイトを占めます。メモ帳を使用してテキスト ファイルを UTF-8 エンコードで保存し、UE でファイルを開いて 16 進編集モードに切り替えると、先頭に FFFE が表示されます。これは、UTF-8 でエンコードされたファイルを識別するための良い方法です。ソフトウェアでは、BOM を使用して、ファイルが UTF-8 でエンコードされているかどうかを識別します。また、多くのソフトウェアでは、読み取るファイルに BOM が必要です。ただし、BOM を認識できないソフトウェアはまだ多くあります。

Firefox の初期のバージョンでは、拡張機能に BOM を含めることはできませんでしたが、Firefox 1.5 以降のバージョンでは BOM のサポートが開始されました。さて、PHP も BOM をサポートしていないことがわかりました。 PHP は設計時に BOM の問題を考慮していませんでした。つまり、UTF-8 でエンコードされたファイルの先頭にある BOM の 3 文字は無視されません。

Bo-Blogのwikiを見ないといけないので、同じくPHPを使っているBo-BlogもBOMに悩まされています。別の問題についても言及されました。「COOKIE 送信メカニズムによる制限により、これらのファイルの先頭にすでに BOM があるファイルでは、COOKIE を送信できません (COOKIE が送信される前に PHP がファイル ヘッダーを送信しているため)。ログイン関数とログアウト関数が無効です。COOKIE と SESSION に依存するすべての関数が無効です。「実行されたファイルには BOM が含まれており、これらの 3 文字が送信されるため、これが WordPress の背景に空白のページが表示される理由です。 Cookie に依存しており、セッション機能が無効です。

解決策は、英語の文字 (または ASCII エンコードの文字) のみが含まれている場合は、ファイルを ASCII コードで保存するだけです。 UE などのエディタを使用する場合は、「ファイル」->「変換」->「UTF-8 to ASCII」をクリックするか、「名前を付けて保存」で ASCII エンコードを選択します。 DOS 形式で終わる行の場合は、メモ帳で開き、[名前を付けて保存] をクリックして、ASCII エンコードを選択します。漢字が含まれている場合は、UE の名前を付けて保存機能を使用して、「UTF-8 without BOM」を選択できます。

BOM は utf-8 に追加すべきではありません。編集者に utf-8 であることを知らせる以外には役に立ちません。実際、エディタは、あまり多くないエンコード形式の特性に基づいてファイルのエンコードを判断することができます。たとえそれが自動的に認識されなかったとしても、エディタにはエンコードを設定する場所が必要です。したがって、utf-8 では BOM は冗長だと思います。

Utf-16 では BOM を追加するだけで済みます。 Unicode 順序でエンコードされるため、BMP 範囲では 2 バイトとなり、ビッグ エンディアンまたはリトル エンディアンとして識別する必要があります。

実際のところ、utf-8 にビッグエンディアンとスモールエンディアンの概念を導入するのはあまりにも愚かだと思います。それらの標準委員会が何を考えているかはわかりません。ビッグエンディアンとスモールエンディアンの存在の意味は、CPU の処理方式にあります。 CPU がビッグ エンディアンを処理する場合、リトル エンディアンでは変換層を実行する必要があり、効率の低下をもたらします。しかし、実際のアプリケーションではエンディアンを気にする人がいるでしょうか?テキストエンコーディングはバイトオーダーの概念を生み出します。標準を策定する人々は厳格すぎるとしか言えません。 UTF-16 については、世界中がバイト順序付け方法に従っている限り、BOM を使用してマークする必要はないと思います。

とはいえ、PHP は UTF-16 でエンコードされたファイルをサポートしていません。たとえば、$ 記号も UTF-8 では 2 バイトであり、PHP デコーダでは解析できないためです。内部処理に Unicode の概念が導入された後、PHP6 がこれをサポートするかどうかはわかりません。

エンコードの問題は単純そうに見えますが、実際には非常に複雑です。多くのプログラムには階層コーディングの概念があります。 MySQL と同様に、クライアント -> 接続 -> ストレージ、ストレージ -> 接続 -> 結果などの概念に分かれています。ストレージはシステム、データベース、テーブル、カラムに分かれています。ここまで複雑にする必要があるのか​​、TNND と時々思う。 MySQL と同様に、その機能を誰が使用するのでしょうか? 2 つのクライアントが異なるエンコード環境で動作することを許可されていない限り、クライアントのエンコードを分離する必要はありません。ほとんどの場合、バイナリ入力/バイナリ出力だけです

上記では、utf-8 と BOM なしの utf-8 の違いを、関連する内容も含めて紹介しています。PHP チュートリアルに興味のある友人に役立つことを願っています。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。