3流プログラマのメモ書き

元開発職→社内SE→派遣で営業支援の三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。(jehupc.exblog.jpから移転中)

(PHP)UTF8でBOMがあるとブラウザ表示時レイアウトがおかしくなる

わかってみれば単純なことなのですが、わかるまで半日を費やしてしまったのでメモしときます。

SmartyUTF-8で書いたテンプレートやら、PHPIE7で表示したらレイアウトが崩れてしまいました。

どうやらCSSで定義してる幾つかが適用されていないみたいです。

SmartyのテンプレートやPHPがUTF8の場合、BOM(Byte Order Mark)付きで保存しているとおかしくなるというのはネットで探して見つけたので、両方のファイルともBOMなしで保存しましたが、結果変わらず。。。おかしいと思い、IE7で表示されたソースをHTMLファイルとして保存し、DIFFツールでSmartyのテンプレートファイルと比較すると、ファイルの先頭に空白らしきものがあるのが発見。

まさかと思い保存したHTMLファイルをバイナリエディタで確認すると、案の定BOMが付いていました。 しかもなぜか2つも。。

こんな感じです。(BOMは16進数で EF BB BF です)

元になっているファイルとSmartyコンパイル後のPHPファイルははBOM無しを確認したのですが、なぜかIEに転送されてきたときはBOMが付いているのです。 そしてBOMが2つもついてる故にIE7は本来ファイルの先頭にあるDOCTYPEを認識できず、互換モードで動いてしまいCSSが解釈できなかったということみたいです。(ちなみにDOCTYPEとブラウザの表示モードについては、DOCTYPE宣言がないとIE7でも表示は古いままDOCTYPE スイッチについてのまとめと一覧表を参照のこと)

どの部分でBOMが付いたのかは不明です。

対処法ですがBOMの削除を参考にさせてもらいました。

 
ob_clean(); //バッファクリア。これで出力時のBOMがのくらしい。
$smarty->display("support_connect_confirm.tpl");

このように ob_clean(); でバッファをクリアすると正常に表示されるようになりました。

 

追伸: BOMが2回でる理由がわかりました。require_onceしてある自作共通モジュールファイルがBOM付きでした。 ということで、ob_clean();をいれなくてもPHP内でよみこんであるファイルのBOMをのぞくだけでOKみたいです。