携帯向けXHTMLを出力する場合に便利なPHPのパッチ

PHPでiモード用XHTMLを出力する際のトラブルと、トラブル対策としてPHPにパッチを当てる方法を紹介します。

ディノの過去の案件で実際にあったことなのですが、携帯向けにXHTMLのコンテンツを表示する際に、PHPで意外なトラブルが発生することがあります。具体的には、下記の状況でmb_output_handlerによる文字エンコーディング変換が効きません。

  • ドコモ携帯向けにXHTMLを出力する
    • Content-Typeを「application/xhtml+xml」とする必要がある(※1)
  • mbstringで外部エンコーディングをSJIS-winに変換したい
    • mb_output_handlerでの文字エンコーディング変換が「text/*」のときにしか有効にならない(※2)

実際、このような状況は十分考えられます。携帯向けのコンテンツをXHTML+CSSで作成することは今後どんどん増えてくるはずですので、Content-Typeを「application/xhtml+xml」とするしか無いでしょう。一方で、もうしばらくは下位機種のためのHTMLをSJIS-winで出力する必要があるでしょうから、外部エンコーディングを全てSJIS-winで統一するのが現実的です。

独自パッチの適用

上記の問題への対策として、ob_ナントカ関数を使って自力で頑張ってもいいのですが、我々はPHPにパッチを当ててしまうことにしました。下記がそのパッチです。(実際にパッチを当てるときは次のリンクを保存してください:php5-mbstring-xhtml-patch

--- php-5.2.5/ext/mbstring/original_mbstring.c	Mon Sep 24 20:51:36 2007
+++ php-5.2.5/ext/mbstring/mbstring.c	Mon Mar 03 18:27:06 2008
@@ -1484,7 +1484,8 @@
 
        /* analyze mime type */
        if (SG(sapi_headers).mimetype &&
-            strncmp(SG(sapi_headers).mimetype, "text/", 5) == 0) {
+            (strncmp(SG(sapi_headers).mimetype, "text/", 5) == 0 ||
+            strncmp(SG(sapi_headers).mimetype, "application/xhtml+xml", 21) == 0)) {
            if ((s = strchr(SG(sapi_headers).mimetype,';')) == NULL){
                mimetype = estrdup(SG(sapi_headers).mimetype);
            } else {

念のためパッチの手順も紹介します。同じディレクトリにphpのソースのtar玉とパッチを用意します。

$ tar xjf php-5.2.5.tar.bz2
$ cd php-5.2.5/
$ patch -p1 < ../php5-mbstring-xhtml-patch.txt

あとは普段通りにmakeすればOKです。PHP 5.2.5のソースコードに対するパッチとして作っていますが、ソースコードをパッと見たところでは、PHP 5.0.0から5.2.5まで全てに同じパッチが当たるかと思います(万一動作しなくても責任は取れませんが…)。

ディノでは過去の案件でこのパッチを実際に利用しています。また、他社さんでも同じ対応をしているところがあると聞きました。ご参考まで。

参考文献

コメント / トラックバック 1 件

#1 トライアウト ラボラトリ! » Blog Archive » » symfonyで携帯用に文字コードをSJISで出力する 2008/06/29 00:43

[...] 株式会社ディノさんのブログ「携帯向けXHTMLを出力する場合に便利なPHPのパッチ」でPHPのソースに直接パッチを当ててる模様。 [...]

コメントする