データベースの文字コードが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から操作するだけで大丈夫なはずです。