0

我正在使用带有 codeigniter 的phpactiverecords 。我想将 PDO::ATTR_EMULATE_PREPARES 设置为 false

我在第 54 行添加PDO::ATTR_EMULATE_PREPARES => false$PDO_OPTIONS文件../lib/Connection.php中。它在以下位置引起未捕获的异常:

../lib/adenter code hereapters/MysqlAdapter.php(76): ActiveRecord\Connection->query('SET NAMES ?', Array)

任何想法?

例外

'42000, 1064, You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1致命错误: /home/waqas/apps/FBI-PHP/sparks/php-activerecord/0.0.2/vendor/php-activerecord/lib/Connection.php:304 中带有消息的未捕获异常 'ActiveRecord\DatabaseException'

堆栈跟踪:

0) /home/waqas/apps/FBI-PHP/sparks/php-activerecord/0.0.2/vendor/php-activerecord/lib/adapters/MysqlAdapter.php(76): ActiveRecord\Connection->query('SET NAMES ?', Array)

1) /home/waqas/apps/FBI-PHP/sparks/php-activerecord/0.0.2/vendor/php-activerecord/lib/Connection.php(108): ActiveRecord\MysqlAdapter->set_encoding('utf8')

2) /home/waqas/apps/FBI-PHP/sparks/php-activerecord/0.0.2/vendor/php-activerecord/lib/ConnectionManager.php(33): ActiveRecord\Connection::instance('mysql://root:@l...')

3) /home/waqas/apps/FBI-PHP/sparks/php-activerecord/0.0.2/vendor/php-activerecord/lib/Table.php(103): ActiveRecord\ConnectionManager::get_connection(NULL)

4) /home/waqas/apps/FBI-PHP/s in /home/waqas/apps/FBI-PHP/sparks/php-activerecord/0.0.2/vendor/php-activerecord/lib/Connection.php on line 304
4

1 回答 1

2

设置连接编码的推荐方法是charset连接 DSN 中的属性:

$dsn = 'mysql:host=localhost;dbname=foo;charset=utf8';
$conn = new PDO($dsn, 'jim', '12345678', $options);

...但此功能需要 PHP/5.3.6 或更高版本。您的库可能会尝试支持旧版本,因此请运行 SQL 命令。细节是你需要运行这个:

SET names=utf8

引用这个论点是行不通的:

SET names='utf8'

ERROR 1064 (42000):您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以获取在 '' 附近使用的正确语法

该库正在使用准备好的语句来运行查询。这是有问题的代码

public function set_encoding($charset)
{
    $params = array($charset);
    $this->query('SET NAMES ?',$params);
}

由于utf8是字符串,因此在技术上需要引用。所以(理论上)你不能使用准备好的语句来运行这样的查询。实际上,如果您使用模拟的准备好的语句,它显然可以正常工作,但在您使用本机语句时却不行:

<?php

$dsn = 'mysql:host=localhost;dbname=test';
$user = 'test';
$pass = 'test';

// Works fine
$pdo = new PDO($dsn, $user, $pass, array(
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => true,
));
$res = $pdo->prepare('SET NAMES ?');
$res->execute(array('utf8'));
unset($pdo);

// Triggers SQL syntax error
$pdo = new PDO($dsn, $user, $pass, array(
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false,
));
$res = $pdo->prepare('SET NAMES ?');
$res->execute(array('utf8'));
unset($pdo);

我的结论是,如果您想按原样使用该库,那您就不走运了:PHP ActiveRecord 似乎不支持本机准备好的语句。

但是,有可能一个简单的补丁就可以解决问题:

// Completely untested!
public function set_encoding($charset)
{
    $this->query('SET NAMES ' . $charset);
}

编辑:我看过你的错误报告。您也省略了异常消息。请注意,存在帮助您的错误消息:您永远不应该丢弃它们!

于 2013-10-10T09:09:07.843 回答