2010/09/25

ZendFrameworkで文字コード変換

ガラケーを対象にしてると、文字コードの変換が必要になります。
DoCoMo と AU は SJIS
SoftBank は UTF-8
いろいろ考えるとアプリケーションは UTF-8 で作って、出力の時に文字コードの変換を
しようって話。



みんなどうやってるかなーってぐぐってみると2つ方法が出てくる。
・Zend_View_Filter で変換。
・Zend_Layout_Controller_Plugin_layout を拡張したクラスでの postDispatch() で変換。
でも結果的にどっちもダメでした。

Zend_View_Filter は Viewスクリプトの中で
<?php echo $this->render('hoge.phtml');?>
とかすると、この render() でフィルターかけてさらに呼んだViewスクリプトにフィルターを
かけるから文字化けする。
2重にフィルターしちゃうんだよね・・・。

次の Zend_Layout_Controller_Plugin_layout の拡張クラスは
一見うまく行ってる。でも
Layoutスクリプト直に日本語書いていると変換してくれない。
もどかしい。

じゃあめんどいからレスポンス吐き出してるとこで変換すりゃいいじゃんってことで、
ご提案。

まず Zend_Controller_Response_Http を継承したクラスを作って outputBody() をオーバーライド。
<?php
class Slumbers_Response extends Zend_Controller_Response_Http
{
    public function outputBody()
    {
        $body = implode("", $this->_body);
        $body = mb_convert_encoding($body, 'SJIS-win', 'UTF-8');
        
        echo $body;
    }
}
次に Bootstrap.php で レスポンスを初期化します。

<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{

    protected function _initResponse()
    {
        $this->bootstrap('FrontController');
        $front = $this->getResource('FrontController');
        $response = new Slumbers_Response();
        $front->setResponse($response);
        
        return $response;
    }
}
これで今んとこ問題起きてない。
と思ったら問題起きてた。
何かしらで変換かましたくない時あるだろうから、Response に何かしら
フラグを変化させるメソッドもたせるといいと思うよ。