_
および%
一般にMySQLのワイルドカードではないため、通常の文字列リテラルに入れる目的でエスケープしないでください。 mysql_real_escape_string
この目的には正しく、十分です。 addcslashes
使用しないでください。
_
および%
LIKE
のコンテキストでのみ特別です -マッチング。 LIKE
でリテラルとして使用する文字列を準備する場合 ステートメント、つまり100%
100%に一致し、100で始まる文字列だけでなく、2つのレベルのエスケープについて心配する必要があります。
1つ目はLIKEエスケープです。 LIKE処理は完全にSQL内で行われ、リテラル文字列をリテラルLIKE式に変換する場合は、パラメータ化されたクエリを使用している場合でも、この手順を実行する必要があります。 !
このスキームでは、_
および%
特別であり、エスケープする必要があります。エスケープ文字もエスケープする必要があります。 ANSI SQLによると、これら以外の文字はすべきではありません エスケープされる:\'
間違っているでしょう。 (ただし、MySQLは通常、それを回避することができます。)
これを実行したら、エスケープの2番目のレベルに進みます。これは、単純な古い文字列リテラルのエスケープです。これはSQLの外部で行われ、SQLを作成するため、LIKEエスケープステップの後に実行する必要があります。 MySQLの場合、これはmysql_real_escape_string
です。 従来通り;他のデータベースには別の機能があります。パラメータ化されたクエリを使用するだけで、それを実行する必要がなくなります。
ここで混乱を招く問題は、MySQLでは、ネストされた両方のエスケープステップのエスケープ文字としてバックスラッシュが使用されていることです。したがって、文字列をリテラルのパーセント記号と照合する場合は、ダブルバックスラッシュエスケープしてLIKE 'something\\%'
と言う必要があります。 。または、それがPHPの場合"
バックスラッシュエスケープも使用するリテラル、"LIKE 'something\\\\%'"
。ああ!
ANSI SQLによると、これは正しくありません。文字列リテラルでは、バックスラッシュはリテラルのバックスラッシュを意味し、一重引用符をエスケープする方法は''
です。; LIKE式では、デフォルトではエスケープ文字はまったくありません。
したがって、移植可能な方法でLIKEエスケープする場合は、デフォルトの(間違った)動作をオーバーライドし、LIKE ... ESCAPE ...
を使用して独自のエスケープ文字を指定する必要があります。 構築します。正気のために、私たちはいまいましいバックスラッシュ以外のものを選びます!
function like($s, $e) {
return str_replace(array($e, '_', '%'), array($e.$e, $e.'_', $e.'%'), $s);
}
$escapedname= mysql_real_escape_string(like($name, '='));
$query= "... WHERE name LIKE '%$escapedname%' ESCAPE '=' AND ...";
またはパラメータ付き(例:PDO):
$q= $db->prepare("... WHERE name LIKE ? ESCAPE '=' AND ...");
$q->bindValue(1, '%'.like($name, '=').'%', PDO::PARAM_STR);
(ポータビリティパーティーの時間をもっと増やしたい場合は、MSSQLServerとSybaseを説明することもできます。[
間違って、文字はLIKE
では特別です ステートメントとエスケープする必要があります。 argh。)