转义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语句中的字符也是错误的,特殊的,必须转义。