Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Постраничный вывод и сортировка

Когда статей сотни, их показывают частями — по десять на странице, со ссылками «1, 2, 3». Это называют постраничным выводом. В Yii число страниц и смещение считает класс Pagination, а ссылки рисует виджет LinkPager.

Pagination в контроллере

// controllers/PostController.php
use yii\data\Pagination;
 
public function actionIndex(): string
{
    $query = Post::find()->where(['status' => 1]);
 
    $pages = new Pagination([
        'totalCount' => $query->count(),
        'pageSize' => 10,
    ]);
 
    $posts = $query
        ->orderBy(['created_at' => SORT_DESC])
        ->offset($pages->offset)
        ->limit($pages->limit)
        ->all();
 
    return $this->render('index', ['posts' => $posts, 'pages' => $pages]);
}

Pagination получает общее число строк и размер страницы, читает номер страницы из параметра адреса page и вычисляет offset и limit для запроса.

Ссылки на страницы

В шаблоне views/post/index.php после списка статей выведите виджет:

<?php
// views/post/index.php
 
use yii\bootstrap5\LinkPager;
?>
 
<?= LinkPager::widget(['pagination' => $pages]) ?>

Под списком появятся ссылки на страницы. Вторая страница открывается по адресу /posts?page=2. Если страница всего одна, виджет ничего не выводит.

Сортировка

Класс Sort разрешает посетителю выбирать порядок строк:

use yii\data\Sort;
 
$sort = new Sort([
    'attributes' => ['title', 'created_at'],
    'defaultOrder' => ['created_at' => SORT_DESC],
]);
 
$posts = Post::find()->orderBy($sort->orders)->all();

В attributes перечислены столбцы, по которым можно сортировать. Передайте $sort в шаблон и выведите ссылку: <?= $sort->link('title') ?>. Щелчок по ней откроет /posts?sort=title, повторный — /posts?sort=-title с обратным порядком.

Поставщик данных

ActiveDataProvider объединяет запрос, постраничный вывод и сортировку в одном объекте:

use yii\data\ActiveDataProvider;
 
public function actionIndex(): string
{
    $dataProvider = new ActiveDataProvider([
        'query' => Post::find()->where(['status' => 1]),
        'pagination' => ['pageSize' => 10],
        'sort' => ['defaultOrder' => ['created_at' => SORT_DESC]],
    ]);
 
    return $this->render('index', ['dataProvider' => $dataProvider]);
}

Считать строки и задавать offset вручную больше не нужно.

ВызовЧто возвращает
$dataProvider->getModels()Статьи текущей страницы
$dataProvider->getTotalCount()Общее число статей
$dataProvider->paginationОбъект Pagination для LinkPager
$dataProvider->sortОбъект Sort

Поставщик данных — основа готовых таблиц и списков, которые разобраны в уроке о виджетах данных.

Частая ошибка

В запросе для поставщика данных не вызывают all(), limit() и offset(). Ему нужен невыполненный запрос: он сам посчитает строки и добавит ограничения. Если передать Post::find()->all(), возникнет ошибка, потому что это уже массив, а не запрос.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.