2010-07-14 82 views
2

我将一个if语句添加到我的数据库抽象层,以挑选出对任意数据库表的任何尝试查询。我的preg_match语法是否有效?

基本上,如果我的应用程序试图创建,读取或销毁数据库表中的数据,称为membersmembers_profiles我想要调用我的if语句。

if (
    preg_match('/INSERT INTO [members|members_profiles]/', $sql) || 
    preg_match('/UPDATE [members|members_profiles]/', $sql) || 
    preg_match('/DELETE FROM [members|members_profiles]/', $sql)) 
{ 
    // do if statement stuff here... 
} 

我不是正则表达式/预浸匹配的主人,但将上述if语句如果SQL查询相匹配返回true:

  • INSERT INTO members ...INSERT INTO members_profiles ...
  • UPDATE members ...UPDATE members_profiles ...
  • DELETE FROM members ...DELETE FROM members_profiles ...

或者是我的preg-match语法关闭?

回答

2

只是一个正则表达式就足够了:

if (preg_match('/(?i)(INSERT\s+INTO|UPDATE|DELETE\s+FROM)(?-i)\s+(members|members_profiles)/', $sql)) 
{ 
    // do if statement stuff here... 
} 

注意(),而不是[]\s+代替空格。因为SQL对于任何数量的空白都是有效的,并且\s+匹配它们全部。 \s后面的+表示它必须至少有一个空格,但它可以更多。 (?i)表示后面的所有字符将被检查为不区分大小写,并且(?-i)会再次打开区分大小写。由于SQL命令不区分大小写。

(abc|def)比赛abcdef
[abc|def]比赛abc|def

要尝试一个正则表达式,你可以使用http://rubular.com/,它说,它是用Ruby编写的测试正则表达式在ruby中,但是有效的正则表达式应该独立于语言,所以它可以用来测试常用的正则表达式,也可以用其他语言。

6

语法是有效的,但不会做你想要的。

对于图案交替,使用

preg_match('/INSERT INTO (?:members|members_profiles)/', $sql) || 
//      ^^^      ^

在PCRE,[…]定义字符类。这将匹配1个字符,因为它出现在括号内。你的情况如果是befilmoprs|_一个[members|members_profiles]将匹配1个字符。使用另一种括号(?:…)进行分组。


(顺便说一句,请使用正则表达式来检测数据库改变的尝试。限制数据库用户的权限来代替。)

+0

这可能要在组的末尾加一个'\ b',并且可以从'\ s *'空间中受益 - 尽管你关于不使用正则表达式的权限当然是有效的。 – 2010-07-14 13:00:28

+0

我没有使用上面的内容来限制数据库访问,但更重要的是,我们正在推出一个新的环境,以便捕获即将被弃用的表的任何引用。这将在一个或两个测试环境中使用,以检查应用程序模型中已更新的所有查询。 – 2010-07-14 13:15:37

0

这是正确的

if (
    preg_match('/INSERT\sINTO\s(members|members_profiles)/', $sql) || 
    preg_match('/UPDATE\s(members|members_profiles)/', $sql) || 
    preg_match('/DELETE\sFROM\s(members|members_profiles)/', $sql)) 
{ 
    // do if statement stuff here... 
} 

LE: 使用空格(s)特殊字符更改空白空间

+1

无需逃离白色空间。 – 2010-07-14 12:53:50

+0

你能解释'preg-match'调用中的反斜杠字符吗? – 2010-07-14 12:54:18

+0

马丁,反斜杠用于转义字符 - 无论是在正则表达式中具有特殊含义的字符,获得字面意义的字符,还是字面赋予特殊含义的字符。 (例如,使用'\\('或'\ |'来获得文字'('或'|'字符,而'\ w'给出“单词字符”的特殊含义等等))在这种情况下,反斜杠不是 – 2010-07-14 12:58:09

2

正则表达式

[ab|cd] 

不匹配或者ab OR cd但符合以下人物之一(!):ab|cd

你需要的是一组,而不是一个字符类:

(ab|cd) 

已经匹配或者ab OR cd

在字符类更多信息:http://www.regular-expressions.info/charclass.html

0

除了其他用户已报告的错误之外,如果您需要检测查询何时尝试更改表格membersmembers_profiles,那么您的正则表达式限制性太强。

我不会用这样的方法,但是如果你需要真正做到这一点,然后考虑

  • 数据库引擎允许发表评论。如果数据库引擎是MySQL,我可以编写INSERT INTO /* little trick */ members …INSERT /* into */ INTO /* table */ members …
  • 数据库引擎允许任意数量的空格或换行符。
+0

这只适用于内部查询;查询来自应用程序的模型,而不是用户生成/用户提交的查询。 – 2010-07-15 20:08:27