これは非常に興味深い質問ですが、答えはそれほど簡単ではありません。
real_escape_string を使用する適切なタイミングは? POST でデータが到着したとき、またはクエリを作成する直前に?
ない
少し説明させてください。
まず、用語を整理しましょう。質問の仕方に間違いが多い。
- real_escape_stringを使用したエスケープではなく、 formatについて話しましょう。エスケープの用途が非常に限られているという理由だけで、これは 1 種類の SQL リテラルの書式設定規則の一部にすぎません。他のタイプでは、異なるフォーマット規則が必要です。
- したがって、データが「POST に到着する」ときの書式設定は問題外です。どのフィールドがクエリのどの位置に入るかわからないため、どのルールを適用すればよいかわかりません。
- 最後になりましたが、POST も他の外部ソースも、クエリの書式設定とはまったく関係ありません。文字列リテラルをクエリに入れる必要がある場合は、source に関係なく、SQL 構文規則に従ってフォーマットする必要があります。数字などについても同様です。
したがって、データをフォーマットする必要がある唯一の適切な時期は、クエリを作成する直前です。
しかし、アプリケーション コードに real_escape_string() を直接適用することは、非常に悪い習慣です。
- 上で述べたように、文字列をフォーマットするにはエスケープだけでは不十分です。文字列の書式設定には、エスケープと引用の両方が含まれます。そのため、SQL クエリの文字列をフォーマットする機能が何であれ、常に一方ではなく両方のタスクを実行する必要があります。引用とエスケープの両方。これらの 2 つのルールは、一方を他方なしで適用するとまったく役に立たないためです。そのため、それらを 1 つの施設で結合することが不可欠です。
- データ型ごとに異なる書式設定規則があることを忘れないでください。数値はその型に明示的にキャストする必要がありますが、エスケープは役に立ちません。
- 手動でエスケープするのはばかげています。繰り返さ
$mysqli->real_escape_string('$test')
れると、コードが肥大化して読みにくくなります。データベース ドライバにすべての書式設定を依頼してみませんか? そのため、最新のテクノロジーに従う必要があります。プレースホルダーを使用してクエリ内のデータを表します。このようなプレースホルダーを処理している間、ドライバーはその場所にあるデータを自動的にフォーマットします。
そして、それは安全で便利になります。
プレースホルダーを簡単に使用する方法は 2 つあります (読みやすさの点で手動エスケープよりも優れていない手動バインドなし)。
- 準備されたクエリで使用する変数を渡すだけなので、PDO を使用します。
したがって、コードは次のようになります
$db->prepare("SELECT * from test_panel where test=?");
$db->execute(array($_POST['test']));
PDOはすべてのフォーマットを内部で行います
- または独自のラッパーを発明してプレースホルダーを実装する
このように
function paraQuery()
{
global $mysqli;
$args = func_get_args();
$query = array_shift($args);
$query = str_replace("%s","'%s'",$query);
foreach ($args as $key => $val)
{
$args[$key] = $mysqli->real_escape_string($val);
}
$query = vsprintf($query, $args);
$result = $mysqli->query($query);
if (!$result)
{
throw new Exception($mysqli->error()." [$query]");
}
return $result;
}
$query = "SELECT * FROM table where a=%s AND b LIKE %s LIMIT %d";
$result = paraQuery($query, $a, "%$b%", $limit);
または、現在のクエリの場合:
$result = paraQuery("SELECT * from test_panel where test=%s", $_POST['test']);
見てください-それは短く、正気で安全になります。