• Блог
  • Метод PDOStatement::fetchAll()

Я не буду здесь рассказывать про xPDO. Про него уже много информации в сети. Например, тут и тут есть примеры с циферками. Я хочу рассказать про интересные возможности метода fetchAll(), который используется для зачитки данных из готового набора данных.

PDOStatement::fetchAll ([ int $fetch_style [, mixed $fetch_argument [, array $ctor_args = array() ]]] )

Этот метод возвращает массив, содержащий все строки результирующего набора. У него есть первый параметр, который определяет содержимое возвращаемого массива. О нём и поговорим.

Многие разработчики часто передают в этот параметр всего одно значение, определяемое константой PDO::FETCH_ASSOC. И на выходе получают ассоциативный массив с ключами из названий столбцов запроса.

$q = $modx->newQuery('modUser');
$q->innerJoin('modUserProfile','Profile');
$q->select('modUser.id,modUser.username,Profile.fullname');
$data = array();
if ($q->prepare() && $q->stmt->execute()) {
    // Зачитываем в ассоциативный массив
    $data = $q->stmt->fetchAll(PDO::FETCH_ASSOC);
}
print_r($data);
// Выведет
Array
(
    [0] => Array
        (
            [id] => 1
            [username] => admin
            [fullname] => Администратор
        )
    [1] => Array
        (
            [id] => 4
            [username] => user1
            [fullname] => Пользователь 1
        )
    [2] => Array
        (
            [id] => 5
            [username] => user2
            [fullname] => Пользователь 2
        )
)

Загоняем массив в foreach() и работаем с каждой строкой данных. Многие это знают и никакой Америки для них я тут не открыл. Давайте рассмотрим ещё несколько режимов.

PDO::FETCH_COLUMN

Возвращает одномерный массив только с одной колонкой. Если в запросе указано несколько полей, то дополнительным параметром можно указать индекс поля для вывода. Если в запросе указать только одно поле, то индекс можно не указывать.

$q = $modx->newQuery('modUser');
$q->innerJoin('modUserProfile','Profile');
$q->select('modUser.id,modUser.username,Profile.fullname');
$data = array();
if ($q->prepare() && $q->stmt->execute()) {
    // Зачитываем поле username
    $data = $q->stmt->fetchAll(PDO::FETCH_COLUMN,1);
}
print_r($data);
// Выведет
Array
(
    [0] => admin
    [1] => user1
    [2] => user2
)

PDO::FETCH_KEY_PAIR

Ещё один интересный режим. Возвращает ассоциативный массив, в котором первое поле указывается в качестве ключа, а второе в качестве значения. Поэтому первое поле должно быть уникальным.

$q = $modx->newQuery('modUser');
$q->innerJoin('modUserProfile','Profile');
$q->select('modUser.id,Profile.fullname');
$data = array();
if ($q->prepare() && $q->stmt->execute()) {
    // Зачитываем в ассоциативный массив id=>fullname
    $data = $q->stmt->fetchAll(PDO::FETCH_KEY_PAIR);
}
print_r($data);
// Выведет
Array
(
    [1] => Администратор
    [4] => Пользователь 1
    [5] => Пользователь 2
)

Требователен к количеству колонок в запросе — их должно быть строго две.

PDO::FETCH_UNIQUE

Похож на предыдущий, но в качестве значения возвращает массив с остальными полями. Очень полезный режим. Главное — первое поле должно быть уникальным.

$q = $modx->newQuery('modUser');
$q->innerJoin('modUserProfile','Profile');
$q->select('modUser.id, modUser.username, Profile.fullname');
$data = array();
if ($q->prepare() && $q->stmt->execute()) {
    // Чтобы зачитать только в ассоциативный массив, нужно добавить через логическое ИЛИ
    // константу PDO::FETCH_ASSOC. Иначе вывод будет как при PDO::FETCH_BOTH 
    $data = $q->stmt->fetchAll(PDO::FETCH_UNIQUE | PDO::FETCH_ASSOC);
}
print_r($data);
// Выведет
Array
(
    [1] => Array
        (
            [username] => admin
            [fullname] => Администратор
        )
    [4] => Array
        (
            [username] => user1
            [fullname] => Пользователь 1
        )
    [5] => Array
        (
            [username] => user2
            [fullname] => Пользователь 2
        )
)

Есть ещё один режим PDO::FETCH_GROUP, который разбивает (группирует) массив по первому полю. Он позволяет вывести события, сгруппированные по дням или товары, сгруппированные по категориям. Я им пока не пользовался, но в голове держу — может пригодится.

$q = $modx->newQuery('modUser');
$q->innerJoin('modUserProfile','Profile');
$q->select('Profile.gender,modUser.username, Profile.fullname');
$data = array();
if ($q->prepare() && $q->stmt->execute()) {
    // Разбиваем на группы и выводим в ассоциативный массив
    $data = $q->stmt->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_ASSOC);
}
print_r($data);
// Выведет массив с двумя группами
// [1] - пользователи мужского пола
// [2] - пользователи женского пола
Array
(
    [1] => Array
        (
            [0] => Array
                (
                    [username] => snejok
                    [fullname] => Саша Белый
                )
        )
    [2] => Array
        (
            [0] => Array
                (
                    [username] => katja
                    [fullname] => Екатерина II
                )
            [1] => Array
                (
                    [username] => lgaga
                    [fullname] => Леди Гага
                )
        )
)
1   6001

Комментарии ()

  1. Alexey 19 января 2021 # +1
    Спасибо, очень интересно!

    PDO::FETCH_GROUP прямо в точку…

    Вы должны авторизоваться, чтобы оставлять комментарии.

    Выделите опечатку и нажмите Ctrl + Enter, чтобы отправить сообщение об ошибке.