3

古い(乱雑な)コードをmysql_query()からPDOに更新中です。

プリペアドステートメントを使用することはセキュリティとパフォーマンスの両方に良いことを理解していますが、パフォーマンスの側面を活用するには、最初にプリペアドを実行し、その後に複数回実行する必要があります。これは、パフォーマンスを向上させる価値がない可能性のあるコードの大幅な書き直しを意味しますが、別の方法でそれを実行できるかどうか疑問に思いました。

私が提案する解決策は、PDOクラスを次のようにラップすることです。

 class PDOCached extends PDO {

      private $PreparedStatementCache;

      public function prepare($query) {

          if (!isset($this->PreparedStatementCache[$query])) {              
                $this->PreparedStatementCache[$query]=parent::prepare($query);
          }

          return $this->PreparedStatementCache[$query];
      }
 }

それは機能します(つまり、同じ結果が返されます)が、パフォーマンスの向上を利用できるかどうかはわかりません。フィードバック/コメントをいただければ幸いです。

注:これでは$ driver_optionsが考慮されていないことはわかっていますが、この演習では重要ではありません。


アップデート:

キャッシュをオプションにするためにクラスを変更しました。

 class PDOCached extends PDO {

      private $PreparedStatementCache;

      // WARNING: Does not take into account $driver_options
      public function prepare($query, $cached=false) {

          if (!$cached) return parent::prepare($query);

          if (!isset($this->PreparedStatementCache[$query])) {  
                // WARNING: Assumes try/catch error handling            
                $this->PreparedStatementCache[$query]=parent::prepare($query);
          }

          return $this->PreparedStatementCache[$query];
      }
 }
4

2 に答える 2

2

技術的なパフォーマンスの観点からは、あなたは正しいです。PDOStatement をキャッシュすることで得られます (同じ接続で使用する必要があります)。しかし、同じ Mysql 接続と PHP リクエスト内でクエリを実行し、次に移動して別のクエリを実行し、最初のクエリに戻る頻度はどれくらいでしょうか? これは混乱を招き、バインドされた変数を誤って変更する可能性が生じるようです (bindParam() を使用する場合)。

これから得られるパフォーマンスの向上は、マイクロ最適化にすぎず、複雑さを増すだけだと思います。ループクエリをクリーンアップするのに時間を費やす必要があるほど複雑であるため、良いことではありません。重複するネストされたクエリが必要です。

ところで:セキュリティだけでも、準備済みステートメントに移行して変換時間を費やす十分な理由があります。

于 2013-01-07T19:56:57.853 に答える
-1

クエリ結果に「永続的に」バインドされる変数の配列をメンバーの 1 つとして含む永続層 PDO ラッパー クラスで、キャッシュされたプリペアド ステートメント パターンを使用しました。このようにして、これを Iterator として使用できました。

于 2020-01-25T15:13:40.200 に答える