7

PDO の ATTR_EMULATE_PREPARES 属性に関する簡単な質問です。簡単に言えば、デフォルト (true) のままにしておくと、すべて正常に動作します。ただし、無効にすると、PHP エラー メッセージすら表示されず、「接続がリセットされました」というブラウザの警告が表示されるだけです。

参考までに、私が使用していたコードのサンプルを次に示します

<?php
include_once("config.php");

try {
  $dbh = new PDO
  (
    "mysql:host=". DB_SERVER .";dbname=" . DB_NAME,
    DB_USER,
    DB_PASS,
    array
    (
      PDO::ATTR_PERSISTENT => true,
      PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
      PDO::ATTR_EMULATE_PREPARES => true
    )
  );
} catch(PDOException $e) {
  echo "<pre>";
  print_r("Error: " . $e);
  echo "</pre>";
  die();
}

$idNum = "1";

$sth = $dbh->prepare("SELECT * FROM `table` WHERE `id` = ?;");
$sth->bindParam(1,$idNum);
$sth->execute();
$res = $sth->fetch();
?>

<pre>
<?=print_r($res); ?>
</pre>

私の素敵なテストテーブルからクエリをうまく返します...

Array
(
    [id] => 1
    [field1] => q12w3e4r5t6y7u8i9
    [field2] => kijhgbfvcdoikujyh
)

しかし、PDO::ATTR_EMULATE_PREPARES の値を false に設定するのは簡単なことではありません。単純に失敗し、元の値に戻すまで再び失敗します。これの原因を突き止めるためにできることはありますか、それとも本当に簡単なことを見逃していましたか?

私のPHPバージョンは現在5.4.3で、MySQLは5.5.24です

4

4 に答える 4

0

こんにちは、あなた (そして私のもの) の問題を解決する方法を見つけました。

同じ問題が発生しました。接続の失敗だけで、エラーはありません。PDO データベース ハンドラーのコンストラクターを呼び出すときに、PDO 構成配列に ATTR_EMULATE_PREPARES オプションを追加したため、何らかの理由で機能しません。どういうわけか、これにより PDO がクラッシュしています。

ATTR_EMULATE_PREPARES オプションを指定せずに PDO データベース ハンドラを開始し、次に setAttribute を使用してエミュレーションを無効にすると、動作します。したがって、次のようになります。

// Configure PDO to really prepare statements and to not emulate them
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

これを読んで、可能であればなぜ ATTR_EMULATE_PREPARES をオフにするのか疑問に思っている人は、以下を読んでください: PDO プリペアド ステートメントの安全性

于 2013-09-10T11:49:54.320 に答える
-2

PHP の MYSQL ドライバーは、準備済みステートメントを実際にはサポートしていないため、パフォーマンスが非常に低くなります。mysql のエミュレートされたステートメントを無効にすると、多くのエラーが発生する可能性があります。

私は数日前にこの問題に頭を悩ませました.

これを持っています:

grik dot net で公開 07-Mar-2012 04:23

PDO_MYSQL では、PDO::ATTR_EMULATE_PREPARES オプションについて覚えておく必要があります。

$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,true); のように、デフォルト値は TRUE です。

これは、$dbh->prepare() 呼び出しで準備済みステートメントが作成されないことを意味します。exec() 呼び出しにより、PDO はプレースホルダーを値自体に置き換え、MySQL に一般的なクエリ文字列を送信します。

最初の結果は、呼び出し $dbh->prepare('garbage'); です。エラーは報告されません。$dbh->exec() 呼び出し中に SQL エラーが発生します。2 つ目は、テーブル名にプレースホルダーを使用するなど、特殊なケースでの SQL インジェクションのリスクです。

エミュレーションの理由は、準備済みステートメントを使用した MySQL のパフォーマンスが低いためです。エミュレーションは大幅に高速に動作します。

出典:ユーザー投稿メモ.

于 2012-11-17T19:06:04.107 に答える