-
Notifications
You must be signed in to change notification settings - Fork 11
fetch
Итак, выполнять запрос мы научились, теперь займёмся разбором полученного результата.
Формат, в котором требуется представить результат, задаётся третьим аргументом метода query().
В примере формат el - одно значение.
$pattern = 'SELECT `email` FROM `users` WHERE `user_id`=?i';
$data = [$userId];
$email = $db->query($pattern, $data, 'el');Если не указать третий аргумент (или указать NULL), query возвращает объект с интерфейсом go\DB\Result уже из которого можно получать результат.
Методы данного объекта соответствуют одноимённый форматам из аргумента query.
То есть следующие три варианта идентичны:
$email = $db->query($pattern, $data, 'el');$email = $db->query($pattern, $data)->el();$result = $db->query($pattern, $data);
$email = $result->el();Имя формата может содержать дополнительные параметры.
При использовании аргумента query(), они записываются через двоеточие после имени формата:
$result = $db->query($pattern, $data, 'assoc:num');При использовании возвращаемого объекта, параметры передаются аргументом в метод разбора:
$result = $db->query($pattern, $data)->assoc('num');В качестве результата в этих случаях возвращается массив, каждый элемент которого соответствует строке в выборке. В случае пустой выборки получается пустой массив.
Результат выборки представляется в виде массива ассоциативных массивов, что примерно соответствует перебору результата через while ($row = mysql_fetch_assoc($res)):
$users = $db->query('SELECT * FROM `users`')->assoc();
echo 'Selected '.count($users).' users';
foreach ($users as $user) {
echo 'Params of another user:';
var_dump($user);
}То есть получается примерно следующее:
[
0 => [
'user_id' => 1,
'name' => 'Vasya',
'age' => 25,
],
1 => [
'user_id' => 5,
'name' => 'Petya',
'age' => 30,
],
2 => [
'user_id' => 8,
'name' => 'Grisha',
'age' => 25,
],
];В случае использования просто "assoc" без дополнительных параметров, получается обычный порядковый массив. Дополнительным параметром можно указать имя столбца, значение из которого будет использоваться в качестве ключа массива. Например, формат "assoc:user_id" вернёт следующий результат:
[
1 => [
'user_id' => 1,
'name' => 'Vasya',
'age' => 25,
],
5 => [
'user_id' => 5,
'name' => 'Petya',
'age' => 30,
],
8 => [
'user_id' => 8,
'name' => 'Grisha',
'age' => 25,
],
);а "assoc:age" следующий:
[
25 => [
'user_id' => 8,
'name' => 'Grisha',
'age' => 25,
],
30 => [
'user_id' => 5,
'name' => 'Petya',
'age' => 30,
],
];Более поздние записи перекрывают более ранние с теми же ключами.
Аналогичный формат, только запись представляется не ассоциативным массивом, а порядковым.
Подобно перебору с mysql_fetch_row().
А этот формат аналогичен перебору с mysql_fetch_object(): каждая запись представляется объектом.
foreach ($db->query('SELECT * FROM `users`')->objects() as $user) {
echo 'Username: '.$user->name."\n";
}Выборка по одному столбцу. В результате: порядковый массив с элементами - значениями заданного столбца.
$usersIds = $db->query('SELECT `user_id` FROM `users`')->col();
var_dump($usersIds); // list of all IDs
$tables = $db->query('SHOW TABLES');
var_dump($tables); // list of all tablesВыборка по двум столбцам, значение первого становится ключом, второго - элементом массива.
Допустим существует таблица "параметров пользователя":
`name` | `value` | `user_id`
"age" | "25" | 1
"sex" | "male" | 1
"status" | "loser" | 1
"age" | "30" | 2
"sex" | "male" | 2
...Следующий запрос выберет все параметры заданного пользователя в виде "параметр" => "значение":
$params = $db('SELECT `name`,`value` FROM `users` WHERE `user_id`=?i', [$userId])->vars();
echo 'Age: '.$params['age'];
echo 'Sex: '.$params['sex'];
echo 'Status: '.$params['status'];Если в выборке один столбец: он становится и ключом и значением.
-
iassoc,iassoc:{$key} -
inumerics,inumerics:{$key} -
iobjects,iobjects:{$key} icolivars
Форматы, аналогичные вышеописанным, только вместо массива возвращается объект, реализующий интерфейс Iterator.
То есть его можно также перебирать, как и массивы.
$users = $db->query('SELECT * FROM `users`')->iassoc();
foreach ($users as $user) {
echo 'Another user:';
var_dump($user);
}Итераторы могут пригодится при выборке очень большого количества данных. Сначала выбирать все эти данные в массив, а потом перебирать уже его, может быть слишком накладным.
Замечание: в текущей версии goDB ещё не реализованы нормально unbuffered-запросы, поэтому толку от итераторов не так много.
При переборе итераторов могут быть некоторые отличия от соответствующих массивов.
При использовании vars или assoc:{$key} в выборке могут встречаться записи с одинаковыми ключами и в массиве останется только последняя из них.
При использовании же итераторов, все записи пройдут через foreach.
Выборка одной строки, это обычно выборка по ID.
Все форматы данной группы возвращают первую строку выборки, если же выборка пуста, то возвращают NULL.
Одна строка в виде ассоциативного массива полей.
$user = $db->query('SELECT * FROM `users` WHERE `user_id`=?i', [$_GET['id']])->row();
if ($user) {
echo 'User params:';
print_r($user);
/*
[
'user_id' => 5,
'name' => 'Vasya',
'age' => 25,
]
*/
} else {
echo 'User not found';
}Тоже самое, только не ассоциативный, а порядковый массив полей.
Одна строка, представленная в виде объекта, чьи поля - поля записи.
$user = $db->query('SELECT * FROM `users` WHERE `user_id`=?i', [$_GET['id']])->object();
if ($user) {
echo 'Username: '.$user->name;
}Выборка по одному значению. Первый столбец первой строки в выборке, или NULL, если выборка пустая.
$email = $db->query('SELECT `email` FROM `users` WHERE `user_id`=?i', [$_GET['id']])->el();
if ($email) {
echo 'User e-mail: '.$email;
} else {
echo 'User not found';
}Как el, только результат приводится к TRUE/FALSE.
Обычно используется для выборки по столбцу с типом "BOOL".
При этом NULL также приводится к FALSE.
Возвращает количество строк в полученной выборке.
Помните, что обычно существуют лучшие способы узнать количество строк, соответствующих условию, чем выбрать их все и посчитать.
Возвращает последний автоинкремент (или его аналог). Используется вместе с операцией вставки.
$set = [
'name' => 'Newcomer',
'age' => 27,
'status' => 'new',
];
$userId = $db->query('INSERT INTO `users` SET ?set', [$set])->id();
echo 'New user ID: #'.$userId;Количество затронутых запросом столбцов.
$ar = $db->query('DELETE FROM `users` WHERE `status`=?', ['loser'])->ar();
echo 'Remove '.$ar.' losers';cursor
Возвращает внутреннее представление курсора, зависящее от адаптера.
Для адаптера mysql (являющегося надстройкой над php_mysqli), это будет mysqli_result.
Используется для более тонкой обработки.
Объект результата (интерфейс go\DB\Result) реализует интерфейс IteratorAggregate и в качестве итератора возвращает объект аналогичный формату iassoc.
То есть можно делать так:
foreach ($db->query('SELECT * FROM `table`') as $row) {
var_dump($row);
}Первая ошибка - использование неизвестного формата разбора.
При попытке вызвать неизвестный метод Result получится обыкновенная PHP-ошибка.
При использовании же неизвестного формата в качестве аргумента query() выбрасывается исключение UnknownFetch.
Вторая ошибка и исключение UnexpectedFetch: неожиданный формат для данного типа результата. Это попытка разобрать результат, не являющийся результатом выборки (курсором), как результат выборки. В примере - попытка представить результат INSERT в виде ассоциативного массива.
$db->query('INSERT INTO `table` SET `a`=?', [5])->assoc();