четверг, 27 июня 2019 г.

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

phpfaq.ru

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


Не пропусти главное событие года - Конференцию веб-разработчиков DevConf!
Москва, 21-22 июня.
Простые запросы
Пример получения колонки и подстановки массива
Условная сборка WHERE
Примеры использования белых списков:
Случай сложной вставки.
Множественный insert
пример с ON DUPLICATE
Пример сложносочинённого запроса
Вставка в запрос оператора NULL
Множественный парсинг
Комментарии (42)
Простые запросы
$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);

Комментариев нет:

Отправить комментарий