-
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}
icol
ivars
Форматы, аналогичные вышеописанным, только вместо массива возвращается объект, реализующий интерфейс 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();