_ および% 一般に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。)