PHP / RegEx - логика для добавления имен таблиц

Итак, я пытаюсь создать сценарий, который автоматически добавляет допустимые имена столбцов к соответствующему префиксу таблицы (например, «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), чтобы гарантировать, что все имена таблиц добавлены правильно?

Могу я спросить, откуда берется SQL, такой как INPUT выше? Можно ли не добавлять префиксы таблиц во время создания SQL или это невозможно?

Luke Woodward 18.01.2009 00:10

Это функция, например buildRecords ($ where = 1, $ orderby = 'id DESC'). Пользователи могут добавить строку $ where без необходимости знать префикс таблицы. Так что нет, это полностью динамично.

Matt 18.01.2009 00:36

Могут ли пользователи вводить предложение WHERE, содержащее любой текст, который им нравится? Прошу прощения, если я вас неправильно понял, но для меня это похоже на риск SQL-инъекции.

Luke Woodward 18.01.2009 01:51

Да. Загвоздка в том, что только зарегистрированные администраторы могут создавать запрос $ where.

Matt 18.01.2009 03:26
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
4
627
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Поразмыслив несколько секунд, я бы решил вот что:

Пройдите по строке, символ за символом, ищите одинарные кавычки, но пропуская экранированные символы. Материал между двумя неэкранированными одинарными кавычками (то есть строки) будет заменен уникальным токеном и помещен в ассоциативный массив с этим токеном в качестве ключа и исходной строкой в ​​качестве значения.

Теперь, когда у нас есть строки, выполните str_replace() (или preg_replace(), если вы настаиваете) для известных имен столбцов. Я бы, вероятно, построил имена столбцов в ассоциативный массив с псевдонимом таблицы в качестве ключа и значением в виде пронумерованного массива, содержащего имена столбцов. Таким образом, замену можно будет автоматизировать.

После того, как имена таблиц будут заполнены, просто выполните str_replace() для токенов, чтобы заменить исходные строки на их места, и все готово.

Я уверен, что кто-то может создать супер-классное (и, вероятно, почти не поддерживаемое) регулярное выражение, чтобы сделать все это за один удар. Но я предпочитаю использовать регулярные выражения только в тех случаях, когда регулярные выражения действительно являются правильным инструментом, а не там, где CFL было бы более подходящим.

Итак, в основном, A) заменить весь текст в одинарных кавычках каким-то случайным ключом, B) заменить имена таблиц с помощью str_replace, C) заменить ключ исходным текстом ...

Matt 18.01.2009 00:11

Этот подход не будет работать, если SQL содержит комментарий с несопоставленным и неэкранированным символом одинарной кавычки.

Luke Woodward 18.01.2009 01:46

Мэтт, это отличный брифинг :). Pourquoi: комментарии могут быть полностью удалены из проанализированного запроса.

Henrik Paul 18.01.2009 13:24

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

Как однажды сказал Джейми Завински: «Некоторые люди, сталкиваясь с проблемой, думают:« Я знаю, я буду использовать регулярные выражения ». Теперь у них две проблемы ».

Что касается создания рабочего процесса, который будет гарантировать, что вы работаете с правильной базой данных, я бы подумал о применении объектно-ориентированного подхода. Классы для таблиц T и R могут быть экземплярами потомков класса модели, ответственного за построение правильного объекта табличного типа с использованием условной логики в том же методе, а не регулярного выражения.

Поздравляем, ваш последний абзац получил награду "Самый технический жаргон". Судя по первым 2 абзацам, я так понимаю, что вы согласны с wolfie ...

Matt 18.01.2009 00:07

«Сделайте вещь, которая может сделать то или другое для вас, чтобы вы сами не облажались». Лучше?

Robert Elwell 18.01.2009 07:11
Ответ принят как подходящий

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

$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);

Другие вопросы по теме