Класс для безопасной работы с MySQL

Фанат

oncle terrible
Команда форума
Это не пользовательская информация, а доверенные конфигурационные данные. Зачем тут плейсхолдеры? Обычные строковые операции РНР еще никто не отменял.
Корректно форматировать надо любые элементы запроса, а не только пользовательские данные.
Случаи бывают разные.

Ну и, если честно, я не вижу предмета спора. Не понадобится такая запись - и хорошо.
 

С.

Продвинутый новичок
Согласен, не самая важная тема для спора. Хотя не могу не заметить, что использование плейсхолдера ?n для имени базы или таблицы не очень коррелирует с термином "корректно". Нельзя идти на поводу за каждым бзиком типа этого или плейсхолдера в данных. Где-то надо остановиться и предоставить разработчику самому решать его собственные экзотические случаи, иначе класс преврашается в очередного мастодонта.
 

Фанат

oncle terrible
Команда форума
Согласен, не самая важная тема для спора. Хотя не могу не заметить, что использование плейсхолдера ?n для имени базы или таблицы не очень коррелирует с термином "корректно".
почему? Это идентификаторный плейсхолдер, а правила форматирования всех плейсхолдеров одинаковы.
Какая проблема использовать его для базы данных?
Где-то надо остановиться и предоставить разработчику самому решать его собственные экзотические случаи, иначе класс преврашается в очередного мастодонта.
Эту фразу не понял
Ну, то есть, с самой мыслью согласен на 100%, но не понял, как она относится к текущему обсуждению.
Вроде бы, зарядить идею fixxxer-а совсем несложно.
 

С.

Продвинутый новичок
Какая проблема использовать его для базы данных?
Виноват, это я с числовым плейсхолдером спутал.
Ну, то есть, с самой мыслью согласен на 100%, но не понял, как она относится к текущему обсуждению.
Ну так немного там, немного здесь и получается куча. Твой класс, сам решай, где черту проводить. Я бы лично оставил упомянутые фичи вне реализации.
 

damner2

Новичок
Фанат
Надеюсь, ты не используешь "уже несколько месяцев" метод whiteList: :)
1. У array_search больше обязательных параметров, так как ща работать не будет
2. Будет notice при вызове whiteList('a', array('b' => 'b'))
3. Есть подозрение, что методам whiteList, filterArray не место в этом классе
 

damner2

Новичок
Фанат
Баловство с LIMIT в getOne, getRow не нужно, так как будет портить легитимные запросы, в которых в конце точка с запятой или комментарий.
 

Фанат

oncle terrible
Команда форума
Фанат
Надеюсь, ты не используешь "уже несколько месяцев" метод whiteList: :)
1. У array_search больше обязательных параметров, так как ща работать не будет
2. Будет notice при вызове whiteList('a', array('b' => 'b'))
3. Есть подозрение, что методам whiteList, filterArray не место в этом классе
Пункты 0 и 3 имеют много общего.
Оба метода именно что добавлены при выделении кода из рабочего класса, для реализации второго пункта правил защиты от инъекций.
Это то самое совмещение идей, о котором я говорил в начале.
при этом я даже ещё не определился окончательно с синтаксисом вайтлиста и алгоритмом его работы. И именно по той причине, по которой возникают вопросы по уместности нахождения его в классе.
По-хорошему, вайтлист должен кидать 404. Но поскольку в классе нет, разумеется, никакой работы с НТТР, то он тупо кидает FALSE, который предполагается ловить в коде.
В общем, всё криво.

Но я, если честно, не вижу альтернатив, если использовать класс в не-MVC окружении.
Инструмент должен быть.
Если будут идеи, как прилепить менее криво, сохраняя безопасность - буду благодарен.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
я не готов к таким вещам.
я уже много раз сталкивался с тем, что "гладко было на бумаге, да забыли про овраги". И всё работает ровно до тех пор, пока #where строится по логике не сложнее, чем implode(' AND ',$w); а там - опять накручивать синтаксис, писать SQL на РНР.
Просто мне кажется, ты пытаешься объектный синтаксис скрестить с процедурным подходом, оттуда и головная боль. Нельзя остаться где-то между, по моему.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Фанат, а тебе не кажется, что ты сам себе сделал эскейпинг и иньекции, только уже в пхп вместо мускула? ;)
Щас у тебя появится myParser_Escape_Placeholders_String() ...
 

fixxxer

К.О.
Партнер клуба
Тут спорно, т.к. с точки зрения ANSI SQL `sth`.`oth` и `sth.oth` — разные идентификаторы, но насколько знаю, так работает только в оракле.
Нафига в имени базы/таблицы точка? По такой логике я могу и ` в имени таблицы захотеть ;)
 

Фанат

oncle terrible
Команда форума
Поскольку я затрудняюсь понять, где чей сарказм и кто кого троллит, сообщения про небезопасные символы я удалил.
Говнокод с вставкой лимита удалю тоже. Это хорошее предложение.
 
  • Like
Реакции: craz

fixxxer

К.О.
Партнер клуба
Ну какой, хоспади, 404, может это вообще крон-скрипт? $this->error() и return false;
 

Фанат

oncle terrible
Команда форума
Так.
Это был Вурдалак.
И я натупил уже минимум на бутылку в его пользу, учитывая и недавний случай. Готов поставить в любое время.

Итак, как временное* решение для "Казуса ~WR~" можно применить регулярку Вурдалака, которая будет обходить вопросы, лежащие в данных.

Остаётся только один вопрос - можно ли вообразить случай, когда вопросы будут встречаться вне строк?
Скажем, кто-то захочет использовать парсер для сборки запросов, которые потом пойдут в ПДО. Маловероятный же сценарий?

Тем не менее, не стоит ли, сейчас, пока на берегу, поменять по-быстрому символ плейсхолдера?
 

fixxxer

К.О.
Партнер клуба
посмотрел внимательно

мысли такие

1) разделить четко raw query и prepared query, prepared можно обернуть в тупой класс с одной строкой внутри например - просто как маркер. preparequery дергать для данной raw query-(под)строки всегда 1 раз
2) добавить плейсхолдер для подстановки части запроса, руками строки не собирать

то есть в итоге в примере WR будет так
PHP:
$one = 'some text with ?s placeholders';

$where = $db->parse("one = ?s",$one); 
assert('$where instanceof SafeMysqlString');
$data = $db->getAll("SELECT * FROM table WHERE ?q LIMIT ?i,?i", $where,$start,$per_page); // $q - (instanceof SafeMysqlString)->__toString()
как вариант - в п.1 проверять если не instanceof SafeMysqlString то prepareQuery.

что-то по типу перлового taint :)
 
Сверху