2011-11-27 12 views
7

PDOを読み、pdoとprepare文についてStackOverFlowを検索しました。私は何が利益であるか、または準備ステートメントを使用しているかを知りたい。例えば:準備を使用して、なぜPHP PDOクエリを準備する

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

$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(); 

を両方のクエリを使用すると、余分なステップを実行する必要があるため、それはつもり遅くなりますように私のためにそれが見えますので、同じ結果を返します。クエリの多くを使用した場合

おかげ

+1

2番目の例は実際には機能しません。クエリのパラメータを値に置き換えていませんでした。 –

+0

@FrancisAvila、まあ、**正しい値を注入できますが、デフォルトでは動作しません。 –

+0

以前のバージョンのOPでは、 '$ calories'は単に':calories'でした。ええ、私のコメントはもはや適用されません。 –

答えて

12

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

  1. 安全:PDOまたは基礎となるデータベース・ライブラリは、あなたのためにバインドされた変数をエスケープするの世話をします。準備されたステートメントを常に使用すると、SQLインジェクション攻撃に対して脆弱になることはありません。
  2. Faster:多くのデータベースでは、準備されたステートメントのクエリプランがキャッシュされ、クエリテキスト全体を再送信する代わりに、準備されたステートメントをシンボルで参照します。これは、文を一度しか準備しないで、用意された文オブジェクトを別の変数で再利用すると最も顕著になります。これら両者の

、#1ははるかより重要であり、準備された文が不可欠になります!プリペアドステートメントを使用していない場合は、ソフトウェアでこの機能を再実装するだけです。 (私は何回かやったとして、私はmysqlドライバを使用することを余儀なくされたとPDOを使用しなかった場合。)あなたは逃した第三の選択肢実際にあり

+0

「ああ、「リトル・ボビー・テーブル」、私たちは彼に電話する...」 http://xkcd.com/327/ – Olie

1

は準備が高速です(すでにクエリを作成し)、それがより安全です。

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

query()では、quote()を使用して手動でクエリを入力する必要があります。これはより多くの作業であり、プログラマを不注意にする傾向があります。あなたの2番目のクエリは、その上で何の防衛を持っていない間

+0

私は問題を修正しました。 – joel

+0

そして、あなたの更新されたコードでは、なぜquery()を使わないでください。今は、単に$カロリーを変更するだけでSQLインジェクションを行うのは簡単です。あなたのprepare()の例はインジェクションプルーフであったでしょう。 –

0

準備し、結合パラメータは、SQLインジェクションを防ぐために意図され、
は、データベースに送信する前に、変数を逃れる行為の同類、
です。

0

$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()をやってしまうと、カーソルオプションを設定するのは少し意味がないようです。