SQLのパラメーター化は、最近のホットなトピックであり、正当な理由がありますが、それは本当に適切にエスケープする以外に何かをしますか?
パラメータ化エンジンは、データをクエリ文字列に挿入する前に、データが適切にエスケープされていることを確認するだけでよいと想像できますが、それだけで十分ですか?たとえば、次のように、接続で別のことを行う方が理にかなっています。
> Sent data. Formatting: length + space + payload
< Received data
-----
> 69 SELECT * FROM `users` WHERE `username` LIKE ? AND `creation_date` > ?
< Ok. Send parameter 1.
> 4 joe%
< Ok. Send parameter 2.
> 1 0
< Ok. Query result: [...]
この方法では、SQLインジェクションの問題が単純に解消されるため、エスケープによって回避する必要はありません。パラメータ化がどのように機能するかを考えることができる他の唯一の方法は、パラメータをエスケープすることです。
// $params would usually be an argument, not in the code like this
$params = ['joe%', 0];
// Escape the values
foreach ($params as $key=>$value)
$params[$key] = mysql_real_escape_string($value);
// Foreach questionmark in the $query_string (another argument of the function),
// replace it with the escaped value.
$n = 0;
while ($pos = strpos($query_string, "?") !== false && $n < count($params)) {
// If it's numeric, don't use quotes around it.
$param = is_numeric($params[$n]) ? $params[$n] : "'" . $params[$n] . "'";
// Update the query string with the replaced question mark
$query_string = substr($query_string, 0, $pos) //or $pos-1? It's pseudocode...
. $param
. substr($query_string, $pos + 1);
$n++;
後者の場合、私はまだ自分のサイトをパラメータ化に切り替えるつもりはありません。私が見ることができる利点はありません、それはただ別の強い対弱い変数タイピングの議論です。強い型付けは、コンパイル時にさらに多くのエラーをキャッチする可能性がありますが、他の方法では困難なことを実際には可能にしません。このパラメーター化と同じです。(間違っている場合は訂正してください!)
アップデート:
- これはSQLサーバー(およびクライアントにも依存しますが、クライアントは可能な限り最高の手法を使用していると思います)に依存することはわかっていましたが、ほとんどの場合、MySQLを念頭に置いていました。ただし、他のデータベースに関する回答も歓迎します(そして歓迎しました)。
- 私が答えを理解している限り、パラメーター化は実際にデータを単にエスケープする以上のことを行います。これは実際にはパラメーター化された方法でサーバーに送信されるため、単一のクエリ文字列としてではなく、変数が分離されます。
- これにより、サーバーはさまざまなパラメーターを使用してクエリを保存および再利用できるようになり、パフォーマンスが向上します。
私はすべてを手に入れましたか?私がまだ興味を持っていることの1つは、MySQLにこれらの機能があるかどうか、そしてクエリの再利用が自動的に行われるかどうか(そうでない場合は、これをどのように行うことができるか)です。
また、誰かがこのアップデートを読んだときにコメントしてください。それが質問か何かにぶつかるかどうかはわかりません...
ありがとう!