cakePHP:初期設定、文字コード周り

· application

cakePHP稼動に向けての設定をメモメモ

前回で、動作はしたけど、文字コード周りでなかなかどうして。。。

文字コード周りの環境確認

作りたいのは携帯サイトってことで、htmlの文字コードはSJISにしたい。

そこでソースもSJIS。DBはEUC_JP。

DBの文字コード

/app/config にあるdatabase.phpを以下のように設定

var $default = array(
		'driver' => 'mysql',
		'persistent' => false,
		'host' => '(host_name)',
		'login' => '(login_id)'
		'password' => '(password)',
		'database' => '(db_name)',
		'encoding' => 'ujis',
	);

ポイントは ’encoding’ => ’ujis’, の部分。

DBのEUC_JPにあわせて設定しました。ところがSJISでDBに入っちゃう。

で、よくよく調べると、 ‘encoding’ => ’ujis’, を設定すると、

SET NAMES ujis

というSQLが発行されている。ふむ・・・何故SJISで入るんだ?

考えたのが、SQLの文字自体はSJISで、とくにSET NAMES したからといってエンコードはされていないのかな?ということ。

そこで、SQLそのものをエンコードしてみる。

SQLの文字コード

参考にさせていただいたのがこちら

はてな:CakePHPとDBの文字コードを別にする方法

そこで /cake/libs/model/app_model.php に以下のメソッドを追記

function beforeFind($queryData) {
        // クエリパラメータの配列を、DB文字コードに変換
        array_walk_recursive($queryData, array($this, 'encodeToDbEncoding'));
        return $queryData;
    }

    function afterFind($results, $primary = false) {
        // 取得結果の配列を、内部文字コードに変換
        array_walk_recursive($results, array($this, 'decodeFromDbEncoding'));
        return $results;
    }

    function beforeSave($options = array()) {
        // saveするデータの配列を、DB文字コードに変換
        array_walk_recursive($this->data, array($this, 'encodeToDbEncoding'));
        return true;
    }

    function query() {
        // Model::queryは可変の引数をとるので同じようオーバーライドにする
        $params = func_get_args();
        array_walk_recursive($params, array($this, 'encodeToDbEncoding'));
        $results = call_user_func_array(array('Model', 'query'), $params);
        if (is_array($results)) {
            $results = $this->afterFind($results);
        }
        return $results;
    }

    function encodeToDbEncoding(&$value, $key) {
        if (is_string($value)) {
            $value = mb_convert_encoding($value, Configure::read('Db.encoding'), Configure::read('App.encoding'));
        }
    }

    function decodeFromDbEncoding(&$value, $key) {
        if (is_string($value)) {
            $value = mb_convert_encoding($value, Configure::read('App.encoding'), Configure::read('Db.encoding'));
        }
    }

参考元から、DBの文字コードをConfigureクラスで設定し、呼び出すよう変更しています。ちなみにConfigureクラスの設定はこちら

/app/config/core.php

/**
 * Db wide charset encoding
 */
	Configure::write('Db.encoding', 'EUC_JP');

これで、DBへの登録、更新、表示がすべて文字化けせずできました。

さて、次は絵文字調査やな・・・・