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'がキャッチされませんでした:304

スタックトレース:

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'

エラー 1064 (42000): SQL 構文にエラーがあります。near '' を使用する正しい構文については、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 に答える