我的数据库中的表是使用正确的UTF-8字符集创建的,如下所示:
CREATE TABLE users (
id INT NOT NULL AUTO_INCREMENT,
...
...
...
...
...
PRIMARY KEY (id)
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_slovak_ci;
但是,当我使用Zend_Db_Table从这个方法中获取表中的数据时:
public function getSingle($id)
{
$select = $this->select();
$where = $this->getAdapter()->quoteInto('id = ?', $id, 'INTEGER');
$select->where($where);
return $this->fetchRow($select);
}
它返回一个带有混乱的UTF-8字符的对象(我猜是转换为iso-8859-1)。
当我通过phpmyadmin查看数据库时,它会正确显示所有字符,并且还显示正确的编码(UTF-8),所以我不知道问题出在哪里。
我该如何解决这个问题?
更新:
所以我做了这个并且它有效:
protected function _initDb()
{
$this->configuration = new Zend_Config_Ini(APPLICATION_PATH
. '/configs/application.ini',
APPLICATION_ENVIRONMENT);
$this->dbAdapter = Zend_Db::factory($this->configuration->database);
Zend_Db_Table_Abstract::setDefaultAdapter($this->dbAdapter);
$stmt = new Zend_Db_Statement_Pdo($this->dbAdapter,
"SET NAMES 'utf8'");
$stmt->execute();
}
有更好的方法吗?
UPDATE2:
我试过了:
protected function _initDb()
{
$this->configuration = new Zend_Config_Ini(APPLICATION_PATH
. '/configs/application.ini',
APPLICATION_ENVIRONMENT);
$this->dbAdapter = Zend_Db::factory($this->configuration->database);
$this->dbAdapter = Zend_Db::factory($this->configuration->database->adapter,
$this->configuration->database->params->toArray()
+ array('driver_options' => array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'")));
Zend_Db_Table_Abstract::setDefaultAdapter($this->dbAdapter);
}
我收到错误:
Fatal error: Undefined class constant 'MYSQL_ATTR_INIT_COMMAND' in C:\wamp\www\bakalarka\application\Bootstrap.php on line 46
答案 0 :(得分:13)
您可以轻松执行以下操作,而不是设置driver_options。
你的ini文件:
db.adapter = Pdo_Mysql
db.params.host = localhost
db.params.dbname = mydb
db.params.username = myuser
db.params.password = mypass
db.params.charset = UTF8
注意最后一个参数。 然后使用Zend_Config_Ini读取您的配置:
$config = new Zend_Config_Ini('application.ini');
并将数据库参数作为config子对象传递:
$db = Zend_Db::factory($config->db);
答案 1 :(得分:3)
我猜你在使用MySQL?我知道强制它返回UTF-8数据的唯一方法是打开数据库连接并运行以下查询:
SET NAMES 'utf8'
或者,如果您使用的是mysqli扩展程序:
mysqli_set_charset('utf8');
也应该有用......
答案 2 :(得分:3)
Wim是正确的。但是,通过使用Zend_Db工厂方法的driver_options
选项,可以在不显式执行查询的情况下执行此操作。我假设您使用pdo_mysql
适配器,并使用Zend_Db的工厂方法对其进行实例化。
您可以使用此工厂方法将其他一组选项传递给适配器。您正在寻找的pdo_mysql
选项是PDO的MYSQL_ATTR_INIT_COMMAND
。
以下是它的工作原理:
$adapterType = 'pdo_mysql';
$adapterConfig = array(
'host' => 'localhost',
'dbname' => 'yourdb',
'username' => 'user',
'password' => 'yourpassword',
// here is where the driver options are defined, as an associative array
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
)
);
$dbAdapter = Zend_Db::factory( $adapterType, $adapterConfig );
如您所见,我们可以使用PDO的MYSQL_ATTR_INIT_COMMAND
选项。你可能知道这个常量在.ini
配置中是不可用的。因此,如果从.ini
文件中读取数据库适配器配置设置,则必须使用.ini
文件中常量的具体值,或者稍后将driver_options数组追加/合并到工厂方法执行中的参数(这就是我所做的),如下:
$dbAdapter = Zend_Db::factory(
$configuration->database->adapter,
$configuration->database->params->toArray() +
array( 'driver_options' => array( PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8' ) )
);
修改强>
我假设只有将一个参数传递给工厂方法,就像在您的示例中一样,这是完全可能的。我习惯于将两个参数传递给工厂方法。