6

MYSQL_ATTR_DIRECT_QUERY私は、デフォルトで PHP PDO がその MySQL ドライバーに対して有効になっているフラグを持っているという事実に遭遇しました (文書化がかなり不十分です) 。

これは、準備済みステートメントを実際に使用するのではなく、準備済みステートメントの動作をエミュレートすることを意味します。これは、クライアント側のプレースホルダーをエスケープされた値に置き換え、完全なクエリをそのままデータベースに送信することを意味します。

古いバージョンの MySQL では、プリペアド ステートメントがクエリ キャッシュをバイパスするため、これを行うには十分な理由がありました。しかし、これはしばらくの間そうではありませんでした。アプリからデータベースへのラウンドトリップの回数が減るため、パフォーマンスがわずかに向上しますが、それだけの価値があるかどうかはわかりません。

この方法を使用することの明らかな欠点は、クライアント側のエスケープにまだ依存していることです。これは通常、悪い考えです。mysqli_real_escape_string過去に、文字セットの設定ミスが原因で無効な文字がクエリに許可されたという奇妙な問題に遭遇しました。このようなことが二度と起こらないようにしたいです。

この問題については、半分真実と表面的なコメントしか見つかりません (たとえば、「はい、有効にできます」または「「問題」が発生します」など)。これをオフにしない本当の理由をお探しですか? とにかくエミュレートされた準備済みステートメントと互換性がないのに、MySQL/PDO で実際の準備済みステートメントを使用していますか?

私が尋ねている理由の 1 つは、PDO に依存する PHPActiverecord を使用しているためです。エミュレートされた準備済みステートメントをオフにすると、特定のエッジケースなどで微妙に動作が変わるため、本番環境で突然中断したくありません。

(補足として、誰かがそれを持ち出す前に:PDO::ATTR_EMULATE_PREPARESMySQLドライバー用に実際に(完全に)実装されていないため、チェックは機能しPDO::MYSQL_ATTR_DIRECT_QUERYません。代わりにチェックする必要があります。ええ、それには時間がかかりました。)

明確にするために:この動作をオフにしない正当な理由があるかどうか疑問に思っています。そもそも気にしてはいけない理由ではありません。

4

1 に答える 1

4

この質問は、エミュレート準備が完全にはサポートされていないという無効な仮定に基づいています。(それらは完全にサポートされています)。

実際、MYSQL_ATTR_DIRECT_QUERY は、ATTR_EMULATE_PREPARES のエイリアスにすぎません。

ソース コードでの証明:接続処理Attribute Getter CodeおよびAttribute Setter Code

セッターコードは最も分かりやすいです。すなわち:

390        case PDO_MYSQL_ATTR_DIRECT_QUERY:
391        case PDO_ATTR_EMULATE_PREPARES:
392            ((pdo_mysql_db_handle *)dbh->driver_data)->emulate_prepare = Z_BVAL_P(val);
393            PDO_DBG_RETURN(1);

エミュレートされた準備を絶対にオフにする必要がある理由の詳細については、この回答を参照してください。

于 2013-09-15T16:53:38.357 に答える