Мой синтаксис preg_match действителен? - PullRequest
2 голосов
/ 14 июля 2010

Я добавляю оператор if в свой уровень абстракции базы данных, чтобы выбрать любые попытки запроса к горстке таблиц базы данных.

По сути, если мое приложение пытается создать, прочитать или уничтожить данные из таблицы базы данных с именем members или members_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...
}

Я не являюсь мастером регулярных выражений / preg-match, но приведенный выше оператор if вернет true, если SQL-запрос соответствует:

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

Или мой синтаксис preg-match выключен?

Ответы [ 5 ]

6 голосов
/ 14 июля 2010

Синтаксис действителен, но не будет делать то, что вы хотите.

Для чередования шаблонов используйте

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

В PCRE […] определяет класс символов. Это будет соответствовать 1 символу, если он указан в скобках. В вашем случае [members|members_profiles] будет соответствовать 1 символу, если это один из b, e, f, i, l, m, o, p, r , s, | или _.

Группировка выполняется с использованием круглых скобок другого типа, (?:…).


(Кстати, не используйте Regex для обнаружения попыток изменения базы данных. Вместо этого ограничьте разрешения пользователя базы данных.)

2 голосов
/ 14 июля 2010

Будет достаточно одного регулярного выражения:

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) соответствует abc или def[abc|def] соответствует a, b, c, |, d, e или f

Чтобы попробовать регулярное выражение, вы можете использовать http://rubular.com/, он говорит, что написано в ruby ​​для тестирования регулярных выражений в ruby, но действительное регулярное выражение должно быть независимым от языка, поэтому его можно использовать для проверки общих регулярных выражений, которые работают и в других языках.

2 голосов
/ 14 июля 2010

Регулярное выражение

[ab|cd]

не соответствует ни ab ИЛИ cd, но соответствует одному из следующих одинарных (!) Символов: a, b, |, c или d.

Вам нужна группа вместо класса символов:

(ab|cd)

, которая соответствует либо ab ИЛИ cd.

Дополнительная информация о классах символов: http://www.regular -expressions.info / charclass.html

0 голосов
/ 14 июля 2010

Помимо ошибок, уже зарегистрированных другими пользователями, ваше регулярное выражение слишком ограничительно, если вам нужно определить, когда запрос пытается изменить таблицы members и members_profiles.

Я бы не стал использовать такой подход, но если вам действительно нужно это сделать, то учтите, что

  • Механизм базы данных позволяет комментировать. Если ядром базы данных является MySQL, я могу написать INSERT INTO /* little trick */ members … или INSERT /* into */ INTO /* table */ members ….
  • Механизм базы данных допускает любое количество пробелов или символов новой строки.
0 голосов
/ 14 июля 2010

Это правильно

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 : изменен пробел, экранированный специальным символом пробела (ов)

...