-
Notifications
You must be signed in to change notification settings - Fork 11
query
Для выполнения запроса к базе данных используется метод query().
Его общий формат:
Result DB::query(string $pattern [[array $data [, string $fetch = null [, string $prefix = null|,]])В следующем примере получаем электронный адрес пользователя по его заранее известным логину и паролю:
use go\DB\DB;
$db = DB::create($params, 'mysql');
$login = 'vasa';
$password = 'qwerty';
$email = $db->query('SELECT `email` FROM `users` WHERE `login`=? AND `password`=?', [$login, $password], 'el');Здесь в одну строчку выполняется сразу три действия:
- На основании шаблона запроса и входных данных формируется SQL-запрос.
- Этот запрос выполняется.
- Результат запроса разбирается в соответствии с заданным форматом и полученное значение записывается в
$email.
Аргумент $pattern, это шаблон запроса.
В нашем случае, это SELECT `email` FROM `users` WHERE `login`=? AND `password`=?.
Входные данные, это данные, которые в нужном порядке вставляются в шаблон.
В нашем случае, это массив [$login, $password - логин и пароль.
На основании шаблона и входных данных генерируется сам SQL-запрос. У нас это будет:
SELECT `email` FROM `users` WHERE `login`="vasa" AND `password`="qwerty"Формат шаблона запроса подробно описан в разделе шаблон запроса.
После выполнения запроса, полученный результат следует привести в нужный нам формат.
Это то самое, что обычно делается через while ($row = mysql_fetch_assoc($result) {...}.
В goDB для этого требуется только указать аргумент $fetch - формат представления результата.
В нашем случае мы выбираем одно значение - email конкретного пользователя.
Указанный нами формат результата el возвращает одно значение: первый столбец первой строки выборки.
Или NULL, если выборка пуста - в нашем случае, это означает, что такого пользователя нет.
$email = $db->query(...)->el();
if ($email) {
echo 'User e-mail: '.$email;
} else {
echo 'User not found';
}Если не указывать $fetch, query() вернёт объект с интерфейсом go\DB\Result, из которого уже можно получить результат.
Следующие три варианта эквивалентны.
$email = $db->query($pattern, $data, 'el');$email = $db->query($pattern, $data)->el();$result = $db->query($pattern, $data);
$email = $result->el();Все варианты разбора подробно описаны в разделе разбор результата.
Четвёртым аргументом метода query() можно указать префикс таблиц, используемый только для этого запроса.
Что это такое и зачем описано в разделе префикс таблиц.
При запросе могут быть выброшены следующие исключения.
Query - ошибка в запросе.
$db->query('SELECT * FORM `table`');
// go\DB\Exceptions\Query: Error SQL "SELECT * FORM `table`";
// error="You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version
// for the right syntax to use near 'FORM `table`' at line 1" [#1064]Инофрмацию об ошибке можно получить из объекта исключения:
try {
$db->query($pattern, $data);
} catch (go\DB\Exceptions\Query $e) {
echo 'Query: '.$e->getQuery()."\n";
echo 'Error: '.$e->getError()."\n";
echo 'Error code: '.$e->getErrorCode()."\n";
}Templater - ошибки в шаблона запроса. Подробно описаны в разделе про шаблон запроса.
Fetch - ошибки при разборе результата. Подробно описаны в разделе про разбор результата.
Connect, Closed - ошибки при отложенном подключении или попытка запроса через закрытое соединение. Подробности см. в разделе про подключение.
В PHP 5.3 появился магический метод __invoke, позволяющий обращаться к объекту, как к функции. Грех было бы его не использовать.
go\DB\DB::__invoke() имеет тот же формат, что и query() и просто делегирует ему вызов.
Выполнять запросы можно через вызов объекта:
$db = DB::create($params);
$user = $db('SELECT * FROM `users`', null, 'row');string makeQuery(string $pattern, array $data [, string $prefix])Данный метод позволяет сформировать запрос на основании шаблона и данных без его выполнения.
Result plainQuery(string $query [, string $fetch])Если запрос уже сформирован, его можно выполнить напрямую через plainQuery.
От query отличается тем, что вместо шаблона и данных на вход подаётся уже готовый SQL-запрос.
$params = [
'_adapter' => 'mysqli',
'_pre' => [
'SET NAMES utf8',
['SET @var=?', ['value']],
],
'host' => 'localhost',
// ...
];
$db = \go\DB\DB::create($params);
$db->query('SELECT @var'); // SET NAMES utf8; SET @var="value"; SELECT @var;Предварительные вопросы выполняются в момент подключения. В случае отложенного подключения - в момент первого запроса. Сами они подключения не инициируют и если не будет никаких других запросов, то и они не выполнятся.
Обычно, это различные конфигурационные настройки.
Первый способ: указать в параметре _pre массив запросов.
Каждому запросу соответствует либо строка - сам запрос, либо массив [шаблон, данные].
Второй способ:
$db = \go\DB\DB::create($params);
$db->preQuery('SET @var=?', ['value']);
$db->query('SELECT @var'); // SET @var="value"; SELECT @var
$db->preQuery('SET @var=2'); // Выполнится сразу, так как подключение естьpreQuery() ничего не возвращает.