7

私はPDOを読み、StackOverFlowでpdoとprepareステートメントについて検索しました。メリットとは何か、または準備ステートメントを使用していることを知りたいです。例えば:

$sql = 'SELECT name, colour, calories FROM fruit WHERE calories < :calories AND colour = :colour';
$sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute(array(':calories' => 150, ':colour' => 'red'));
$red = $sth->fetchAll();

vs

$sql = "SELECT name, colour, calories FROM fruit WHERE calories < $calories AND colour = $colour";
$result = $connection->query($query);
$row = $result->fetch(PDO::FETCH_ASSOC);

どちらのクエリも同じ結果を返すので、prepareを使用すると、余分な手順を実行する必要があるため、処理が遅くなるように見えます。

ありがとう

4

4 に答える 4

12

プリペアドステートメントは次のとおりです。

  1. より安全:PDOまたは基盤となるデータベースライブラリが、バインドされた変数のエスケープを処理します。プリペアドステートメントを常に使用する場合、SQLインジェクション攻撃に対して脆弱になることはありません。
  2. (時々)より速く:多くのデータベースは、準備されたステートメントのクエリプランをキャッシュし、クエリテキスト全体を再送信する代わりに、シンボルによって準備されたステートメントを参照します。これは、ステートメントを1回だけ準備してから、準備されたステートメントオブジェクトをさまざまな変数で再利用する場合に最も顕著になります。

これら2つのうち、#1ははるかに重要であり、準備されたステートメントが不可欠になります。プリペアドステートメントを使用しなかった場合、唯一の正しいことは、この機能をソフトウェアに再実装することです。(私がmysqlドライバーを使用することを余儀なくされ、使用できなかったときに私が数回行ったようにPDO。)

于 2011-11-27T14:19:22.383 に答える
1

多くのクエリを使用する場合(既にクエリを準備している場合)、準備はより高速であり、より安全です。

2番目のコードはおそらく機能しません。クエリでパラメータを使用していますが、それらを定義していません。

query()では、quote()を使用して手動でクエリを入力する必要があります。これはより多くの作業であり、プログラマーを不注意にする傾向があります。

于 2011-11-27T14:09:33.140 に答える
0

パラメータの準備とバインドはSQLインジェクションを防ぐことを目的としており
、データベースに送信する前に変数をエスケープするような行為ですが
、2番目のクエリにはそれに対する防御がありません。

于 2011-11-27T14:14:13.210 に答える
0

あなたが逃した3番目のオプションが実際にあります:

$stmt = $dbh->prepare( '
   SELECT 
       name, 
       colour, 
       calories 
   FROM fruit 
   WHERE calories < :calories 
     AND colour = :colour
');
$stmt->bindParam( ':calories', $calories, PDO::PARAM_INT );
$stmt->bindParam( ':colour', $colour, PDO::PARAM_STR, 64 );
if ( $sth->execute() )
{
   $data = $sth->fetchAll( PDO::FETCH_ASSOC);
}

何かが足りないかもしれませんが、fetchAll()とにかくやることになるのであれば、カーソルオプションを設定するのは少し無意味に思えます。

于 2011-11-27T14:27:16.810 に答える