Примеры использования

Простые запросы
Пример получения колонки и подстановки массива
Условная сборка WHERE
Примеры использования белых списков:
Случай сложной вставки.
Множественный insert
пример с ON DUPLICATE
Пример сложносочинённого запроса
Вставка в запрос оператора NULL
Множественный парсинг
Комментарии (50)

Простые запросы

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


Пример получения колонки и подстановки массива

$ids = $db->getCol("SELECT id FROM tags WHERE tagname = ?s",$tag);
$data = $db->getAll("SELECT * FROM table WHERE category IN (?a)",$ids);


Условная сборка WHERE

$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 ?p LIMIT ?i,?i",$where, $start,$per_page);


Примеры использования белых списков:

$allowed = array('title','url','body','rating','term','type');
$data = $db->filterArray($_POST,$allowed);
$sql = "INSERT INTO ?n SET ?u";
$db->query($sql,$table,$data);


Функция whiteList служит для проверки переданной строки по белому списку.
пример "мягкой" проверки:
$order = $db->whiteList($_GET['order'],array('name','price'),'name');
$dir = $db->whiteList($_GET['dir'],array('ASC','DESC'),'ASC');
$sql = "SELECT * FROM table ORDER BY $order $dir LIMIT ?i,?i"
$data = $db->getAll($sql, $start, $per_page);

здесь мы проверяем имя поля и направление сортировки. Если соответствие не нашлось, то автоматически подставляется дефолтное значение.

Но по-хорошему, если нам вместо нормального имени поля прислали неведомую ерунду - надо бы ответить адекватной ошибкой. В этом случае нужно просто не указывать дефолтное значение:
$order = $db->whiteList($_GET['order'],array('name','price'));
if ($order === FALSE) {
throw http404; // или ваш собственный способ выдать 404 ошибку
}


Случай сложной вставки.

Гибкость, о которой говорилось выше, заключается в том, что мы не ограничены синтаксисом специализированной функции, например, insert. К примеру, чтобы выполнить запрос INSERT IGNORE, мы просто пишем
$sql = "INSERT IGNORE INTO ?n SET ?u";
$db->query($sql,$table,$data);

а в случае с функцией нам пришлось бы дописывать к ней новые параметры, нагромождая новый, неочевидный синтаксис.

Или такой пример: основной массив данных лежит в $data, но при этом два поля заполняются вручную,
поскольку в них используются функции mysql.
$data = array('field'=>$value,'field2'=>$value);
$sql = "INSERT INTO table SET ts=unix_timestamp(), ip=inet_aton(?s),?u";
$db->query($sql, $ip, $data);

обычной функцией insert() мы бы не смогли здесь воспользоваться

Множественный insert

$ins = array();
foreach ($data as $row) {
$ins[] = $db->parse("(NULL,?s,?s, NOW())",$row['name'],$row['lastname']);
}
$instr = implode(",",$ins);
$db->query("INSERT INTO table VALUES ?p",$instr);


пример с ON DUPLICATE

$data = array('offers_in' => $in, 'offers_out' => $out);
$sql = "INSERT INTO stats SET pid=?i,dt=CURDATE(),?u ON DUPLICATE KEY UPDATE ?u";
$db->query($sql,$pid,$data,$data);


Пример сложносочинённого запроса
Имея массив
$count = array(1 => 10, 2 =>13, 5 => 123, 17 => 43)
получить запрос
UPDATE `rules`
SET `used_at` = NOW(), `times_used` = `times_used` + CASE `id`
WHEN 1 THEN 10
WHEN 2 THEN 13
WHEN 5 THEN 123
WHEN 17 THEN 43
END
WHERE id IN(1, 2, 5, 17)


С использованием функции parse() получается довольно компактный код
$when = '';
foreach($count as $rule_id => $rule_count) {
$when .= $db->parse("WHEN ?i THEN ?i ",$rule_id, $rule_count);
}
$sql = "UPDATE rules SET used=NOW(),times=times + CASE id ?p END WHERE id IN(?a)");
$db->query($sql,$when,array_keys($count));


Вставка в запрос оператора NULL
Я долго размышлял над этим вопросом, и сначала решил не добавлять NULL автоматом.
Но потом на гитхабе получил issue от человека, который передавал AJAX-ом JSON, в котором была куча NULL-в, и которому было бы дико удобно сразу пихать раскодированный json в запрос, одной строчкой:

$db->query("INSERT INTO t SET ?u", json_decode($input));

Но нуллы ему все портили и он уговорил меня переделать.

А потом я уже узнал, что PDO и Mysqli тоже отправляют NULL в базу, если ты делаешь prepared statement и передаешь в него переменную, которая содержит NULL. Так что это самое правильное поведение.

В итоге, сейчас такой код

echo $db->parse("INSERT INTO t (col) VALUES (?s)", NULL);

выведет

INSERT INTO t (col) VALUES (NULL)

- что, оказывается, невероятно удобно!

Множественный парсинг
$text = "text with ?s placeholder. let's go";
$where = $db->parse("name = ?s",$text);
$subsel = $db->parse("SELECT id FROM test WHERE ?p",$where);
$data = $db->getAll("SELECT * FROM test WHERE id IN(?p) OR id>?i",$subsel,1);