Типы и параметры запросов

Комментарии: 2  Просмотры: 20 922

Продолжаем работать с базой данных в Кохане и в этом уроке мы познакомимся с различными типами запросов, ведь кроме запросов на выборку данных очень часто используются запросы на их добавление, обновление и удаление. Ну и естественно, какие запросы без параметров, особенно добавление.
В прошлом уроке делалась выборка всех статей из базы данных. Чтобы выбрать только одну запись (статью) с определенным идентификатором, необходимо условие. Напишем его:

$query = DB::query(Database::SELECT, 'SELECT * FROM articles WHERE id = :id');
$query->param(':id', $id);

В данном случае в специальный параметр :id подставится значение переменной $id. Эту связку «параметр-переменная» мы передаем, используя специальный метод param. Такая форма записи называется Prepared Statements (Подготовленные операторы). Она позволяет избежать SQL-инъекций.

SQL-инъекция — один из распространённых способов взлома сайтов и программ, работающих с базами данных, основанный на внедрении в запрос произвольного SQL-кода.
Внедрение SQL, в зависимости от типа используемой СУБД и условий внедрения, может дать возможность атакующему выполнить произвольный запрос к базе данных (например, прочитать содержимое любых таблиц, удалить, изменить или добавить данные), получить возможность чтения и/или записи локальных файлов и выполнения произвольных команд на атакуемом сервере. Атака типа внедрения SQL может быть возможна из-за некорректной обработки входных данных, используемых в SQL-запросах. Разработчик прикладных программ, работающих с базами данных, должен знать о таких уязвимостях и принимать меры противодействия внедрению SQL.

Естественно, параметров может быть несколько. В принципе в таком случае можно использовать несколько вызовов метода param, каждый раз со своими значениями, но лучше использовать метод parameters, где передавать эти значения в виде ассоциативного массива. Пример:

$query = DB::query(Database::SELECT, 'SELECT * FROM users WHERE username = :user AND status = :status') 
    ->parameters(array(    
        ':user' => 'john',    
        ':status' => 'active',
));

В случае, если мы определяем значение переменных в запросе после самого запроса, то по аналогии с Видом мы можем использовать метод bind. Это может быть полезно, если требуется вызов одного запроса, но с разными параметрами много раз:

$query = DB::query(Database::INSERT, 'INSERT INTO users (username, password) VALUES (:user, :pass)')    
    ->bind(':user', $username)    
    ->bind(':pass', $password); 
 
foreach ($new_users as $username => $password)
{    
    $query->execute();
}

В массиве $new_users ключом служит имя пользователя, а значением — его пароль. Мы в цикле проходим по всему массиву, вставляя в таблицу users новых пользователей. Обратите внимание, что для примера дан уже запрос INSERT. Как вы могли заметить, синтаксис запросов абсолютно аналогичен обычным SQL-запросам, только с использованием подготовленных операторов.
Еще, для примера, запросы UPDATE:

DB::query(Database::UPDATE, 'UPDATE users SET email = :email WHERE id = :id')
    ->parameters(array(
        ':email' => $email,
        ':id'    => $id,
));

и DELETE:

DB::query(Database::DELETE, 'DELETE FROM users WHERE email = :email')
    ->param(':email', $email);

Важно понимать, что запросы в таком виде еще не будут выполнены. Это просто их генерация, в чем нетрудно убедиться, вызвав оператор echo и получив результат вида «DELETE FROM users WHERE email = ‘misha@mail.ru’». При этом даже соединения с базой не происходит. Чтобы запрос сработал, нужно в конце вызвать метод execute(). По умолчанию при работе с базой используется соединение default (мы его настраивали в конфигурационном файле database.php). Для использования другого соединения достаточно передать его название в этот метод. Например:

DB::query(Database::DELETE, 'DELETE FROM users WHERE email = :email')
    ->param(':email', $email)
    ->execute('alternate');

Или еще один вариант записи, более длинный (рекомендую пользоваться коротким):

    Database::instance('alternate')->query(Database::DELETE, 'DELETE FROM users WHERE email = :email')
    ->param(':email', $email)
    ->execute();

Это была теория. В следующем уроке мы немного попрактикуемся на примере нашего блога, после чего перейдем к замечательному инструменту Query Builder.

<< Назад | Вперед >> | Обсудить на форуме


К записи оставлено 2 коммент.

Очень долго мучился пытаясь вытащить один элемент по id
из-за неправильных точки с запятой вот а подсказка для таких как я )
»
public function get_all()
{
$id = ’1′;
return DB::query(Database::SELECT, «SELECT * FROM articles WHERE id = :id»)
->param(‘:id’, $id)
->execute();
}

«

подскажите, каким образом можно сделать множественную вставку одним запросом? аналог запроса:
INSERT INTO users (username, password) VALUES ($user1, $pass1),($user2, $pass2),($user3, $pass3)



Оставить комментарий или два

Пожалуйста, зарегистрируйтесь для комментирования.