Итак, я пытаюсь создать сценарий, который автоматически добавляет допустимые имена столбцов к соответствующему префиксу таблицы (например, «t.» Или «r.»).
$t_columns = array('id', 'name', 'label');
$r_columns = array('related_value');
ВХОД:
id > 1 AND (name = 'Hello' OR label IN ('World', 'Planet name AND label')) AND (related_value > 1 AND related_value < 50)
ВЫХОД:
t.id > 1 AND (t.name = 'Hello' OR t.label IN ('World', 'Planet name AND label')) AND (r.related_value > 1 AND r.related_value < 50)
Обратите внимание на то, что вы не можете сделать обычный str_replace. Какой был бы самый простой код (я предполагаю preg_replace), чтобы гарантировать, что все имена таблиц добавлены правильно?
Это функция, например buildRecords ($ where = 1, $ orderby = 'id DESC'). Пользователи могут добавить строку $ where без необходимости знать префикс таблицы. Так что нет, это полностью динамично.
Могут ли пользователи вводить предложение WHERE, содержащее любой текст, который им нравится? Прошу прощения, если я вас неправильно понял, но для меня это похоже на риск SQL-инъекции.
Да. Загвоздка в том, что только зарегистрированные администраторы могут создавать запрос $ where.






Поразмыслив несколько секунд, я бы решил вот что:
Пройдите по строке, символ за символом, ищите одинарные кавычки, но пропуская экранированные символы. Материал между двумя неэкранированными одинарными кавычками (то есть строки) будет заменен уникальным токеном и помещен в ассоциативный массив с этим токеном в качестве ключа и исходной строкой в качестве значения.
Теперь, когда у нас есть строки, выполните str_replace() (или preg_replace(), если вы настаиваете) для известных имен столбцов. Я бы, вероятно, построил имена столбцов в ассоциативный массив с псевдонимом таблицы в качестве ключа и значением в виде пронумерованного массива, содержащего имена столбцов. Таким образом, замену можно будет автоматизировать.
После того, как имена таблиц будут заполнены, просто выполните str_replace() для токенов, чтобы заменить исходные строки на их места, и все готово.
Я уверен, что кто-то может создать супер-классное (и, вероятно, почти не поддерживаемое) регулярное выражение, чтобы сделать все это за один удар. Но я предпочитаю использовать регулярные выражения только в тех случаях, когда регулярные выражения действительно являются правильным инструментом, а не там, где CFL было бы более подходящим.
Итак, в основном, A) заменить весь текст в одинарных кавычках каким-то случайным ключом, B) заменить имена таблиц с помощью str_replace, C) заменить ключ исходным текстом ...
Этот подход не будет работать, если SQL содержит комментарий с несопоставленным и неэкранированным символом одинарной кавычки.
Мэтт, это отличный брифинг :). Pourquoi: комментарии могут быть полностью удалены из проанализированного запроса.
Я не знаю, подходит ли здесь регулярное выражение. Я бы сказал, что выполнение валидации на PHP с минимальным увеличением вычислительной сложности стоило бы. Затем, если ваша база данных потребует каких-либо изменений, вам не придется выдергивать волосы, беспокоясь о том, как повысить надежность вашего регулярного выражения.
Как однажды сказал Джейми Завински: «Некоторые люди, сталкиваясь с проблемой, думают:« Я знаю, я буду использовать регулярные выражения ». Теперь у них две проблемы ».
Что касается создания рабочего процесса, который будет гарантировать, что вы работаете с правильной базой данных, я бы подумал о применении объектно-ориентированного подхода. Классы для таблиц T и R могут быть экземплярами потомков класса модели, ответственного за построение правильного объекта табличного типа с использованием условной логики в том же методе, а не регулярного выражения.
Поздравляем, ваш последний абзац получил награду "Самый технический жаргон". Судя по первым 2 абзацам, я так понимаю, что вы согласны с wolfie ...
«Сделайте вещь, которая может сделать то или другое для вас, чтобы вы сами не облажались». Лучше?
Это можно сделать разными способами, в том числе с помощью регулярного выражения. Я лично использовал бы массивный подход. Прежде всего, я бы определил таблицу искажений следующим образом:
$table = array(
'id' => 't.id',
'name' => 't.name',
'label' => 't.label',
'related_value' => 'r.related_value'
);
Это значительно упростит вызов str_replace ():
function mangling(&$v, $k, $table)
{
if (($k & 1) == 0)
$v = str_replace(array_keys($table), array_values($table), $v);
}
$spans = explode("'", ' ' . $input);
array_walk($spans, 'mangling', $table);
$output = implode("'", $spans);
Могу я спросить, откуда берется SQL, такой как INPUT выше? Можно ли не добавлять префиксы таблиц во время создания SQL или это невозможно?