How to make PDO run SET NAMES utf8 each time I connect, In ZendFramework

和自甴很熟 提交于 2019-11-26 21:41:11

Itay,

A very good question. Fortunately for you the answer is very simple:

database.params.driver_options.1002 = "SET NAMES utf8"

1002 is the value of constant PDO::MYSQL_ATTR_INIT_COMMAND

You can't use the constant in the config.ini

fear my google-fu

$pdo = new PDO(
    'mysql:host=mysql.example.com;dbname=example_db',
    "username",
    "password",
    array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));

first hit ;)

just put this in your config

database.params.charset = "utf8"

or after ZF 1.11 this would work to resources.db.params.charset = utf8 that is it

The connection in zend_db is lazy which means it connects on the first query. if you have a static page with no query's in it it will never even connect - even if it is initialized in you bootstrap file.

so running:

$db->query("SET NAMES 'utf8'");

Is not so smart. Big thanks to dcaunt for his solution.

All this methods shoud work, except in some special circumstances. For example, if you are running a web server locally on a windows machine with php < 5.3.1, only a 'manual' $db->query("SET NAMES 'utf8'"); before your actual query will work. Any other method trying to use MYSQL_ATTR_INIT_COMMAND will fail.

Here's what I learnt today, struggling with this very problem :

  1. You can't refer to PDO::MYSQL_ATTR_INIT_COMMAND in some environments (i.e. mine, specifically I don't know). You have to explicitely use 1002 instead

  2. With Zend Framework 1.11 ( perhaps since 1.8, to be confirmed ), you don't need to set database.params.driver_options.1002 = "SET NAMES utf8" in your config.ini : resources.db.params.charset = "utf8" will be enough for Zend_Db_Adapter_Pdo_Mysql to do it for you.

  3. On windows, you need php >= 5.3.1 for MYSQL_ATTR_INIT_COMMAND to work.

  4. If you replace your php version with 5.3.1 or higher (I also tested 5.3.3), you need to make sure you set a value to pdo_mysql.default_socket in your php.ini. The default empty value won't work (to be confirmed : I read something about this but didn't bother to try without it after finding out about point 5)

  5. You also need to make sure you have '127.0.0.1 localhost' in your windows\system32\drivers\etc\hosts hidden system file (that wasn't a problem for php 5.3.0)

With all this in mind, you should be able to save from yourself a day of googling and keep some of your hairs! ;)

You just have to execute this command before you start queries, you only have to execute it once before the queries and not for every query.

$pdo->query("SET NAMES 'utf8'");

Full example

$servername = "localhost";
$username = "root";
$password = "test";
$dbname = "yourDB";

try {
    $pdo = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);

    $pdo->query("SET NAMES 'utf8'");

    //set the PDO error mode to exception
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $sql = "SELECT name FROM nations";
    foreach ($pdo->query($sql) as $row) {
       echo "<option value='".$row['name']."'>".$row['name']."</option>";
    }


} catch(PDOException $e) {
    echo "Error: " . $e->getMessage();
}
$pdo = null; 

In your bootstrap file...

$db = Zend_Db::factory($adapter, $config);
$db->query("SET NAMES 'utf8'");

then you save this instance in your registry

Zend_Registry::set('db', $db);
wormhit
$table->getAdapter()->query('SET NAMES UTF8');
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!