2

我的数据库中的表是使用正确的 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();
}

有没有更好的方法?

更新2:

我试过这个:

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
4

3 回答 3

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');

并将数据库参数作为配置子对象传递:

$db = Zend_Db::factory($config->db);
于 2011-02-10T18:46:12.997 回答
3

我猜你正在使用MySQL?我知道强制它返回 UTF-8 数据的唯一方法是打开数据库连接并运行以下查询:

SET NAMES 'utf8'

或者,如果您使用的是 mysqli 扩展:

mysqli_set_charset('utf8');

应该也可以...

于 2010-02-11T20:21:50.573 回答
3

维姆是正确的。但是,有一种方法可以在不显式执行查询的情况下执行此操作,方法是使用driver_optionsZend_Db 工厂方法的选项。我假设您使用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' ) )
);

编辑
我认为这完全有可能只需将一个参数传递给工厂方法,就像您在示例中所做的那样。我只是习惯了将两个参数传递给工厂方法的习惯。

于 2010-02-11T20:42:19.023 回答