STRICTモードなMySQLにCodeIgniterセッションをDB保存する際に注意すること

とある案件でちょっとハマったので覚書程度に書いておきます。

そもそもの発端

ご存知の通りCodeIgniterのセッションはちょっと特殊で、その性質上、私はDBに保存することがほとんどです。
で、いつも通りにやっててもDBに保存されないので「なんで!?」とアレコレやった結果です。
結論から言いますと、解決策はいたってシンプルです。

STRICTモードでの動作?

$db['default']['db_debug'] = FALSEにしてたせいで解決に時間がかかってしまいました・・・デバッグ大事。

STRICTモードとは、

MySQL::MySQL 5.1 リファレンスマニュアル::4.2.6 SQL モード

にあるように、厳格なモードで動作させるみたいです。このMySQLがこのモードで動作している場合CodeIgniterのSessionクラスがエラーになります。
エラーはこんな感じです。

メッセージからするに、user_dataカラムに初期値が設定されてないのが原因のようでした。
user_dataカラムは通常TEXTタイプにすると思うので、DEFAULT値を設定するのはダメですね。

コード修正とか

新規セッションデータを作成する際に問題があるようなので、CI_Session::sess_create()メソッドにデフォルト値を追記します。


function sess_create()
{
$sessid = '';
while (strlen($sessid) < 32)
{
$sessid .= mt_rand(0, mt_getrandmax());
}

// To make the session ID even more secure we'll combine it with the user's IP
$sessid .= $this->CI->input->ip_address();

$this->userdata = array(
'session_id' => md5(uniqid($sessid, TRUE)),
'ip_address' => $this->CI->input->ip_address(),
'user_agent' => substr($this->CI->input->user_agent(), 0, 50),
'last_activity'=> $this->now
);

// デフォルト値を設定
$this->userdata['user_data'] = '';

// Save the data to the DB if needed
if ($this->sess_use_database === TRUE)
{
$this->CI->db->query($this->CI->db->insert_string($this->sess_table_name, $this->userdata));
}

// Write the cookie
$this->_set_cookie();
}


赤字の部分のように、user_dataカラムに空文字列をセットして動作させたところ、上手くセッションが開始されました!
新規セッションデータのINSERTなので、空文字列でいいと思います。

まとめ

クエリを発行してモードチェックと処理分岐まで書いてたのですが、「そこまでせんでも…」と思い直ってやめました。
そもそもMySQLの動作モードまでアプリケーションで吸収することじゃないよね、と思ったりしたので。

1行追記するだけなので、コアライブラリにそのまま書いちゃっていいかもしれませんが、そもそもSTRICTモードで動いている
MySQLが稀かもなので、困った時に追記すればいいですかね。

ちなみに、CodeIgniter2.0系でもこの処理は変わらずでした。

以上、私的な覚書でした。