在这个方案中,_
和%
是特殊的,必须转义。转义字符也必须被转义。根据ANSI SQL,除这些以外的字符必须不能被转义:\'
将是错误的。 (尽管MySQL通常会让你摆脱困境。)
完成此操作后,您继续进行第二级转义,这是一种普通的旧字符串文字转义。这发生在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);
(如果您想了解更多的便携性派对的时候,你也可以有乐趣试图解释MS SQL Server和Sybase,其中[
字符也是错误的,在LIKE
声明中是特殊的,并且必须被转义。)
我会再次为“该死的反斜杠!”+1。 – BoltClock 2010-09-10 10:30:35
谢谢,现在只是吸收这个...这真的帮助我扩展我的基本知识。愚蠢的是,尽管我并没有使用任何LIKE语句,并且由于我认为(请确认)%和_在LIKE语句中是疯狂的,我实际上正在逃避%和_,实际上我正在浪费我的时间。但是,这让我想到你为什么要在LIKE语句的上下文中转义%或_。当然,使用LIKE语句的唯一原因是你可以使用它的通配符。 (请原谅我在这方面的有限知识) – Columbo 2010-09-10 11:06:05
当然,但希望能够搜索文字'%'或'_'字符是非常自然的。如果用户在前端搜索'50%',那么他们可能意味着他们正在寻找一个包含'50%'的字符串,而不是任何含有'50'的字符串。 – bobince 2010-09-10 11:08:29