SOHOゆいちのサイト
Bsheもそうですが、私は最近PHPのプログラムのエンコードはたいていUTF-8で書いています。
ですが、データベースは前のシステムとの兼ね合いなどでEUC-JPなどが利用されていることが多いため、Zend_Db_Table関係を少し機能追加して、Zend_Db_Table_RowクラスとZend_Db_Table_RowsetクラスにtoArrayの他にtoMbArrayメソッドを追加してみました。
array_walkから呼び出す用の以下の関数を用意しておきます。
function arrayMbConvertEncoding(&$item, $key, $arrayConfig)
{
$toEncoding = $arrayConfig[0];
$fromEncoding = $arrayConfig[1];
if (is_string($item)) {
$item = mb_convert_encoding($item, $toEncoding, $fromEncoding);
}
}
Dbクラスで保持して、テーブルクラスではDbクラスからの値を取得してもいいと思いますがここでは、Dbのエンコードをテーブルクラスで保持するようにします。
class Cshe_Db_Table extends Zend_Db_Table
{
/**
* DBのエンコーディング
*
* @var unknown_type
*/
protected $dbEncoding;/**
* mainDBの接続を自動設定するコンストラクタ
*
* @param config
*/
public function __construct($config = null)
{
try {
// DBエンコーディングセット
if( isset( $config['db_encoding']))
{
$this->dbEncoding = $config['db_encoding'];
unset( $config['db_encoding']);
}
// row,rowsetクラス設定
$config['rowClass'] = ‘Cshe_Db_Table_Row’;
$config['rowsetClass'] = ‘Cshe_Db_Table_Rowset’;// 親クラスのコンストラクタ
parent::__construct($config);
}
catch(Exception $e)
{
throw $e;
}
}/**
* Databaseのエンコーディングを設定する。
*/
public function getDbEncoding()
{
return $this->dbEncoding;
}
}
これで、テーブルクラスをインスタンス化するときに、以下のようにすることで、エンコードをセットできます。
$db = Zend_Db::factory(‘Pdo_Mysql’, array(
‘host’ => ‘*****’,
‘username’ => ‘*****’,
‘password’ => ‘*****’,
‘dbname’ => ‘*****’
));
$tbl = New Cshe_Db_Table(array(‘name’ => ‘*****’, ‘db’ => $db, ‘db_encoding’ => ‘***’));
RowクラスにtoMbArray(toArrayにエンコード変換を加えたもの)メソッドを追加し、__getメソッドをオーバーライドします。
class Cshe_Db_Table_Row extends Zend_Db_Table_Row
{/**
* エンコーディングをDBから、PHP内部エンコードに変更して返す
*
*/
public function toMbArray()
{
$toEncoding = ini_get( ‘mbstring.internal_encoding’);
try {
$arrayTmp = $this->toArray();
array_walk_recursive($arrayTmp, ‘arrayMbConvertEncoding’, array($toEncoding, $this->_table->getDbEncoding()));
return $arrayTmp;
}
catch( Exception $e)
{
throw $e;
}
}/**
* getにマルチバイト対応を適用
*
*/
public function __get($columnName)
{
$toEncoding = ini_get( ‘mbstring.internal_encoding’);$columnName = $this->_transformColumn($columnName);
if (!array_key_exists($columnName, $this->_data)) {
require_once ‘Zend/Db/Table/Row/Exception.php’;
throw new Zend_Db_Table_Row_Exception("Specified column \"$columnName\" is not in the row");
}
return mb_convert_encoding( $this->_data[$columnName], $toEncoding, $this->_table->getDbEncoding());
}
}
RowsetクラスにtoMbArray(toArrayにエンコード変換を加えたもの)メソッドを追加します。
class Cshe_Db_Table_Rowset extends Zend_Db_Table_Rowset
{/**
* エンコーディングをDBから、PHP内部エンコードに変更して返す
*
*/
public function toMbArray()
{
$toEncoding = ini_get( ‘mbstring.internal_encoding’);
try {
$arrayTmp = $this->toArray();
array_walk_recursive($arrayTmp, ‘arrayMbConvertEncoding’, array($toEncoding, $this->_table->getDbEncoding()));
return $arrayTmp;
}
catch( Exception $e)
{
throw $e;
}
}
}
これで、以下のようにすると、文字コードを変換したデータをRowsetから取得できるようになります。
$db = Zend_Db::factory(‘Pdo_Mysql’, array(
‘host’ => ‘*****’,
‘username’ => ‘*****’,
‘password’ => ‘*****’,
‘dbname’ => ‘*****’
));
$tbl = New Cshe_Db_Table(array(‘name’ => ‘*****’, ‘db’ => $db, ‘db_encoding’ => ‘***’));$rowset = $tbl->fetchAll();
$arraytmp = $rowset->toMbArray();
www.bshe.org (created by itassist.info)