Класс сделан для реализации трёх основополагающих идей:
1. Окончательное решение проблемы SQL инъекций.
2. Повышение удобства работы с БД, сокращение рутинных операций.
3. Максимальная гибкость при относительной простоте.
идеи соединялись с некоторым скрежетом и результат получился с некоторыми врождёнными недостатками, увы.
Тем не менее, основной функционал, внедренный на работе в имевшийся ранее класс для работы с БД отработал уже несколько месяцев без особых нареканий.
Самое главное - это, разумеется, безопасность.
Которую я сформулировал из двух правил:
1. данные подставляем в запрос только через плейсхолдеры
2. идентификаторы и ключевые слова подставляем только из белого списка, прописанного в нашем коде.
Соответственно, класс должен предоставлять возможность следовать этим двум правилам.
Забегая вперёд скажу, что 100% защиты от дурака не получилось, и это оказался единственный компромисс в пользу простоты и удобства за счёт безопасности.
Для плейсхолдеров ключевым моментом является их типизованность. Которая убивает двух жирных зайцев:
- обеспечивает корректное форматирование любых частей запроса
- грандиозно упрощает синтаксис.
Для белосписочности предоставлены две функции, которые инкапсулируют примитивный пхп код.
Для удобства сделаны хелперы, как в PEAR:
B или DBdimple. Ничего нового, просто возможность сразу получить результат запроса в желаемом виде.
Плюс пара кастомных плейсхолдеров, которые облегчают формирование сложных операторов.
пример:
Простота и гибкость.
Основная идея состоит в том, что мы работаем только с SQL. Никаких методов, забирающих себе функциональность SQL (и ограничивающих её).
Всё что можно, автоматизируется с помощью плейсхолдеров:
Т.е. большинство стандартных запросов пишутся тупыми однострочниками.
Для любых же нестандартных случаев у нас НЕТ специальных методов. Всё делается той же самой тупой ручной сборкой SQL-я как и раньше.
Но из безопасных кусков.
Здесь на первый план выходит метод parse(), которому по барабану, что парсить - хоть целый запрос, хоть его часть.
Переменная $where - тот самый компромисс, о котором я говорил выше.
Да, это переменная, подставляемая прямо в запрос.
Да, у пользователя должно хватать ума, чтобы подставлять только те переменные, которые вышли из рук метода parse(), и были составлены с соблюдением всё тех же правил.
но если соблюдать это нехитрое условие, код работы с SQL становится максимально компактным и в то же время максимально безопасным.
Вводная статья на хабре: http://habrahabr.ru/post/165069/
Документация лежит тут: Класс для защиты от SQL инъекций, с примерами и пояснениями
Код https://github.com/colshrapnel/safemysql/blob/master/safemysql.class.php
Очень бы хотелось фидбека по двум линиям:
Первая - это, естественно, функционал. Вопросы о применению, идеи по улучшению.
Вторая - синтаксис. Я не великий классописатель, и все новейшие достижения программистской мысли прошли мимо меня стороной. поэтому буду рад привести кд в соответствие самым модным веяниям. единственное условие - сохранение принципа plug and play - портабельность и сохранение низкого порога вхождения, не требующего возведения поддерживающего фреймворка.
1. Окончательное решение проблемы SQL инъекций.
2. Повышение удобства работы с БД, сокращение рутинных операций.
3. Максимальная гибкость при относительной простоте.
идеи соединялись с некоторым скрежетом и результат получился с некоторыми врождёнными недостатками, увы.
Тем не менее, основной функционал, внедренный на работе в имевшийся ранее класс для работы с БД отработал уже несколько месяцев без особых нареканий.
Самое главное - это, разумеется, безопасность.
Которую я сформулировал из двух правил:
1. данные подставляем в запрос только через плейсхолдеры
2. идентификаторы и ключевые слова подставляем только из белого списка, прописанного в нашем коде.
Соответственно, класс должен предоставлять возможность следовать этим двум правилам.
Забегая вперёд скажу, что 100% защиты от дурака не получилось, и это оказался единственный компромисс в пользу простоты и удобства за счёт безопасности.
Для плейсхолдеров ключевым моментом является их типизованность. Которая убивает двух жирных зайцев:
- обеспечивает корректное форматирование любых частей запроса
- грандиозно упрощает синтаксис.
Для белосписочности предоставлены две функции, которые инкапсулируют примитивный пхп код.
Для удобства сделаны хелперы, как в PEAR:

Плюс пара кастомных плейсхолдеров, которые облегчают формирование сложных операторов.
пример:
PHP:
$data = array('offers_in' => $in, 'offers_out' => $out);
$sql = "INSERT INTO stats SET pid=?i,dt=NOW(), ?u ON DUPLICATE KEY UPDATE ?u";
$this->db->query($sql,$pid,$data,$data);
Основная идея состоит в том, что мы работаем только с SQL. Никаких методов, забирающих себе функциональность SQL (и ограничивающих её).
Всё что можно, автоматизируется с помощью плейсхолдеров:
PHP:
$name = $db->getOne('SELECT name FROM table WHERE id = ?i',$_GET['id']);
$data = $db->getInd('id','SELECT * FROM ?n WHERE id IN ?a','table', array(1,2));
$data = $db->getAll("SELECT * FROM ?n WHERE mod=?s LIMIT ?i",$table,$mod,$limit);
Для любых же нестандартных случаев у нас НЕТ специальных методов. Всё делается той же самой тупой ручной сборкой SQL-я как и раньше.
Но из безопасных кусков.
Здесь на первый план выходит метод parse(), которому по барабану, что парсить - хоть целый запрос, хоть его часть.
PHP:
$w = array();
$where = '';
if ($one) $w[] = $db->parse("one = ?s",$one);
if ($two) $w[] = $db->parse("two IN (?a)",$two);
if ($tre) $w[] = $db->parse("tre <= ?i",$tre);
if (count($w)) $where = "WHERE ".implode(' AND ',$w);
$data = $db->getAll("SELECT * FROM table $where LIMIT ?i,?i", $start,$per_page);
Да, это переменная, подставляемая прямо в запрос.
Да, у пользователя должно хватать ума, чтобы подставлять только те переменные, которые вышли из рук метода parse(), и были составлены с соблюдением всё тех же правил.
но если соблюдать это нехитрое условие, код работы с SQL становится максимально компактным и в то же время максимально безопасным.
Вводная статья на хабре: http://habrahabr.ru/post/165069/
Документация лежит тут: Класс для защиты от SQL инъекций, с примерами и пояснениями
Код https://github.com/colshrapnel/safemysql/blob/master/safemysql.class.php
Очень бы хотелось фидбека по двум линиям:
Первая - это, естественно, функционал. Вопросы о применению, идеи по улучшению.
Вторая - синтаксис. Я не великий классописатель, и все новейшие достижения программистской мысли прошли мимо меня стороной. поэтому буду рад привести кд в соответствие самым модным веяниям. единственное условие - сохранение принципа plug and play - портабельность и сохранение низкого порога вхождения, не требующего возведения поддерживающего фреймворка.
Последнее редактирование: