MySQLで使用するとき、MySQLのバージョンによっては接続直後に set names utf8 のような文字コードを確定させるためのクエリーを投げる必要があります。4.1系ではたしか必須でしたね。5.x系ではどうだったかな。
Akelos で set names を投げるとき、config/boot.php の末尾に次のコードを書くとよいです。
// set names charset
if (!defined('AK_SET_NAMES')) {
require_once(AK_LIB_DIR.DS.'AkActiveRecord.php');
global $dsn;
$dao =& Ak::db(&$dsn);
$dao->Execute('set names utf8');
unset($dao);
define('AK_SET_NAMES', true);
}
これなら、Akelosから投げられるすべてのSQLより前に、set names をセットすることができます。
すでにネット上では次のような方法が紹介されています。
SET NAMES utf8を指定する方法 [Akelos学習法]
⇒この方法は、
オフィシャルのフォーラムで出てきた解決方法なのですが、この方法には1つ大きな問題があります。
Akelos には AK_SESSION_HANDLER という定数がありますが、これを1にセットしておくと、セッション情報がファイル管理からDB管理に切り替わります。(セッション用のDBは下記のカラムで事前に作成しておく必要があります)
mysql> desc sessions;
+---------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+-------+
| id | varchar(64) | NO | PRI | NULL | |
| expire | datetime | YES | | NULL | |
| value | longtext | YES | | NULL | |
+---------------+-------------+------+-----+---------+-------+
セッションをDB管理にしておくと、アプリが成長して複数ホストで運用したくなったときに効果を発揮します。ということで、できればセッションはファイル管理よりもDB管理にしておきたいところですが、set names を ApplicationController の コンストラクタに入れておくと、
プログラム開始時にセッション機能がスタートする
(select * from sessions where id = セッションID が実行される)
↓
ApplicationController::__constructor() の中で set names utf8 が実行される
という順番にSQLが発行されます。
このとき、Akelos の中でセッションデータがうまく取得できず、以降の処理でセッションの更新が一切できなくなります。セッションは最初に作成されたのみで、更新はされないものになる、ということですね。
すると、アプリ側から
$this->session['foo'] = 'bar';
のようにセッションに値をセットしても動かず、
$this->flash['notice'] = "更新しました";
$this->redirectTo(array('action' => 'finish'));
のような、リダイレクト先でメッセージを表示させる処理も動かなくなります。セッションに値を入れる動作ができず、セッションに保存したはずの値はすべてからっぽになってしまう、ということですね。
ということで、ApplicationController::__constructor() で set names をやるのは、セッションをDBで管理する場合に不具合を発生させるため、やらない方がよいでしょう。一方、セッションをファイル管理で行う(AK_SESSION_HANDLER が false )場合、ApplicationController::__constructor() 内で set names は効きます。これはプログラム開始時のセッションDBへのクエリが発生しなくなるため、set names が常に最初のクエリとなるためです。
もうひとつ紹介されている情報。
Akelosでmysqlの文字化けをどうにかする [ぬかるむ日々]
こちらはフレームワークのソースコードを直接変更する方法。
この方法は基本的に何の問題もありませんが、フレームワーク自体のアップデートなどの作業を考えると、できれば直接編集は避けたいかな、といったところ。もともと僕もこの方法で対応していたんですけどね。
この記事へのコメント