转义MySQL通配符
在旧的服务器上,我正在使用,我不能使用准备好的语句我目前正试图完全逃避用户input之前,发送到MySQL。 为此,我使用PHP函数mysql_real_escape_string
。
由于这个函数不能逃避MySQL通配符%和_,所以我使用addcslashes
来转义这些。
当我发送像这样的东西:
test_test " '
到数据库再读回数据库显示:
test\_test " '
看这个,我不明白为什么_有一个前面的反斜杠,但是“和”不是,因为它们全都用\确定地转义了_'和“应该都是相同的,即所有的转义符都可见或所有没有它可见。
逃跑是自动筛选出来的
任何人都可以解释吗?
_
和%
在MySQL中通常不是通配符,为了将它们放到正常的string文字中,不应该转义。 mysql_real_escape_string
对于这个目的是正确和充分的。 addcslashes
不应该被使用。
_
和%
仅在LIKE
匹配的情况下是特殊的。 当你想在LIKE
语句中为字面使用准备string时, 100%
匹配百分之百而不是任何以百个字符开始的string,你有两个级别的转义担心。
首先是LIKE逃跑。 LIKE处理完全在SQL内部进行,如果要将文字string转换为文字LIKEexpression式,则即使使用参数化查询,也必须执行此步骤!
在这个scheme中, _
和%
是特殊的,必须被转义。 逃生angular色也必须逃脱。 根据ANSI SQL,除了这些以外的字符不能被转义: \'
会是错的。 (尽pipeMySQL通常会让你摆脱困境。)
完成这个之后,你继续进行第二级转义,这是一个普通的旧string文字转义。 这发生在SQL之外,创buildSQL,因此必须在LIKE转义步骤之后完成。 对于MySQL,这是mysql_real_escape_string
,如前所述; 对于其他数据库将有不同的function,你可以使用参数化查询,以避免必须这样做。
这里导致混淆的问题是,在MySQL中使用反斜线作为转义字符的嵌套转义步骤! 所以,如果你想匹配string百分号,你将不得不使用双反斜杠转义,并且说LIKE 'something\\%'
。 或者,如果这是在一个也使用反斜杠转义的PHP文字中, "LIKE 'something\\\\%'"
呃!
根据ANSI SQL,这是不正确的,它说:在string文字反斜杠意思是文字反斜杠和逃避单引号的方式是''
; 在LIKEexpression式中,默认情况下根本没有转义字符。
所以,如果你想以一种可移植的方式使用LIKE-escape,你应该使用LIKE ... ESCAPE ...
结构重写默认(错误)行为并指定自己的转义字符。 为了理智,我们会select除了该死的反斜杠以外的东西!
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
语句中的字符也是错误的,特殊的,必须转义。