データベースの文字コードがsjisで、ソースコードはUTF8という状況です。
基本的にはdatabase.phpの設定でsjisの設定をするだけで使えます。
'default' => array( 'datasource' => 'Mysql' 'persistent' => false, 'host' => 'host', 'login' => 'login', 'password' => 'password', 'database' => 'database', 'prefix' => '', 'encoding' => 'sjis', ),
ただし、このままだとphpの5C問題に引っ掛かります。
特定の文字で文字化けを起こします。
回避するためにMysql.phpのconnectメソッドをオーバーライドします。
PDOを作る時のデータベース接続文字列にエンコードの指定をしてあげます。
継承するクラスは下記にあります。
Cake\Model\Datasource\Database\Mysql.php
phpは5.3,cakeは2.2というバージョンで動作確認していますが、
2系の最新のcakeでもMysql.phpのソースが変っていなかったので同じだと思います。
下記の場所にクラスを作って、database.phpのdatasourceで作成したクラスを指定します。
必要があれば、App::buildでパスを追加して下さい。
私の場合は、かなりディレクトリ構成を変えていたため、追加する必要がありました。
App\Model\Datasource\Database\MysqlCharaSet.php
<?php App::uses('DboSource', 'Model/Datasource'); App::uses('Mysql', 'Model/Datasource/Database'); class MysqlCharaSet extends Mysql { public function connect() { $config = $this->config; $this->connected = false; try { $flags = array( PDO::ATTR_PERSISTENT => $config['persistent'], PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ); if (!empty($config['encoding'])) { $flags[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $config['encoding']; } if (empty($config['unix_socket'])) { $dsn = "mysql:host={$config['host']};port={$config['port']};dbname={$config['database']}"; } else { $dsn = "mysql:unix_socket={$config['unix_socket']};dbname={$config['database']}"; } if (!empty($config['encoding'])) { $dsn .= ';charset='.$config['encoding']; } $this->_connection = new PDO( $dsn, $config['login'], $config['password'], $flags ); $this->connected = true; } catch (PDOException $e) { throw new MissingConnectionException(array('class' => $e->getMessage())); } $this->_useAlias = (bool) version_compare($this->getVersion(), "4.1", ">="); return $this->connected; } }
この部分が追加した処理です。 PDO自体に使用する文字コードを教えてあげることで適切な処理をエスケープをしてくれるようになります。
if (!empty($config['encoding'])) { $dsn .= ';charset='.$config['encoding']; }
あとは、通常通りModelから操作するだけで大丈夫なはずです。