日本語のカラム名を使った時に文字化けする

既存のデータベース(SQLServer)からデータを取得するAPIを作成しようとした時に躓いたので残しとく。
SQLServerは初めてだったのですが、テーブル名やカラム名を日本語にすることが多いんですかね。
MySQLとかも日本語のカラム名使う場合があるみたいなのでそういう時にも変換が必要だと思います。

取得した内容を出力すると、データは表示されるけど、カラム名が文字化ける。
調べるとカラム名sjis で、データは utf8 でした。

まずは Config/database.php の encoding を修正してみる。がエラーになる。
charsetを付け足すと文字コードは変わるが、カラム名とデータの文字コードが入れ替わるだけでやっぱり片方文字化ける。

DB設定では直りそうにないので、コア部分でカラム名文字コードだけ utf8 に変換するようにしました。


app/Model/Datasource/Database/AppSqlserver.php を作成します。

<?php
class AppSqlserver extends Sqlserver {

	public function resultSet($results) {
		$this->map = array();
		$numFields = $results->columnCount();
		$index = 0;

		while ($numFields-- > 0) {
			$column = $results->getColumnMeta($index);
+			$name = mb_convert_encoding($column['name'], 'utf8', 'sjis');

			if (strpos($name, '__')) {
				if (isset($this->_fieldMappings[$name]) && strpos($this->_fieldMappings[$name], '.')) {
					$map = explode('.', $this->_fieldMappings[$name]);
				} elseif (isset($this->_fieldMappings[$name])) {
					$map = array(0, $this->_fieldMappings[$name]);
				} else {
					$map = array(0, $name);
				}
			} else {
				$map = array(0, $name);
			}
			$map[] = ($column['sqlsrv:decl_type'] == 'bit') ? 'boolean' : $column['native_type'];
			$this->map[$index++] = $map;
		}
	}
}

app/Config/database.php で作成した datasource を読み込むようにする。

<?php
class DATABASE_CONFIG {

	public $default = array(
-		'datasource' => 'Database/Sqlserver',
+		'datasource' => 'Database/AppSqlserver',
		'persistent' => false,
		'host' => 'localhost',
		'login' => 'root',
		'password' => '*********',
		'database' => 'database',
	);
}

カラム名・データともに utf8 で出力されるようになりました。
encoding とか charset で指定した文字コードを利用するようにしたほうがいいのですが、そこまでやってません。

以上。