2010-07-14 3 views
2

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

В принципе, если мое приложение пытается создать, прочитать или уничтожить данные из таблицы базы данных, которая называется 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 матча, но будет выше if оператор возвращает истину, если SQL запрос соответствует:

  • 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 действителен с любым количеством пробелов nay, а \s+ соответствует всем этим. + за \s означает, что это должно быть хотя бы одно пробел, но это может быть больше. Значение (?i) означает, что все следующие символы будут проверяться нечувствительными к регистру, а снова включите чувствительность регистра (?-i). Поскольку команды SQL нечувствительны к регистру.

(abc|def) матчей abc или def
[abc|def] матчи a, b, c, |, d, e или f

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

6

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

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

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

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

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


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

+0

Это, вероятно, означает '\ b' в конце группы и будет полезно использовать пробелы' \ s * '- хотя ваша точка зрения о том, что вы не используете регулярное выражение для разрешений, конечно, действительна. –

+0

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

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: Исправлено выделение пробелов с пробелами (специальными символами)

+1

Не нужно бежать. –

+0

Вы могли бы объяснить, что делает символ обратной косой черты в вызовах 'preg-match'? –

+0

Мартин, обратная косая черта используется для того, чтобы избежать символов - те, которые имеют особое значение в регулярном выражении, чтобы получить буквальный, или те, которые являются буквальными, чтобы придать особое значение. (например, используйте '\\ (' или '\ |' для получения буквенных '(' или '' 'символов, в то время как' \ w' дает специальное значение «символов слова» и т. д.). В этой ситуации обратная косая черта не является –

2

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

[ab|cd] 

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

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

(ab|cd) 

, который делает соответствовать либо ab ИЛИ cd.

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

0

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

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

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

Это только для внутренних запросов; запросы, поступающие из моделей приложения, а не запросы, созданные пользователем/пользователем. –

Смежные вопросы