Пагинация в CodeIgniter: полное руководство
Russian (Pусский) translation by Ilya Nikov (you can also view the original English article)
Преимущество использования любого фул-стек фреймворка заключается в том, что вам не нужно беспокоиться об общих задачах, таких как обработка ввода, проверка формы и т.п., Поскольку фреймворк уже предоставляет оболочку для этих функций. Таким образом, он позволяет вам сосредоточиться на бизнес-логике приложения, а не повторно изобретать колесо снова и снова.
Сегодня мы собираемся изучить важную библиотеку фреймворка CodeIgniter - библиотеку пагинации.
Позвольте мне выделить темы, которые мы рассмотрим в ходе этой статьи:
- Демонстрация основного пейджинга
- Изучение параметров настройки
- Конфигурация разбиения на страницы
Демонстрация основного пейджинга
В этом разделе мы рассмотрим пример, демонстрирующий использование разбивки на страницы в CodeIgniter. Это лучший способ понять, как все работает.
В нашем примере мы создадим довольно простой список пользователей, в котором мы будем извлекать записи из таблицы users MySQL. Чтобы успешно запустить этот пример, убедитесь, что у вас есть поля uid
и uname
в вашей таблице users.
С этой настройкой мы готовы к работе.
Двигаемся дальше и создаем файл контроллера controllers/Paging.php
со следующим содержимым.
1 |
<?php
|
2 |
defined('BASEPATH') OR exit('No direct script access allowed'); |
3 |
|
4 |
class Paging extends CI_Controller { |
5 |
public function __construct() |
6 |
{
|
7 |
parent::__construct(); |
8 |
|
9 |
// load Pagination library
|
10 |
$this->load->library('pagination'); |
11 |
|
12 |
// load URL helper
|
13 |
$this->load->helper('url'); |
14 |
}
|
15 |
|
16 |
public function index() |
17 |
{
|
18 |
// load db and model
|
19 |
$this->load->database(); |
20 |
$this->load->model('Users'); |
21 |
|
22 |
// init params
|
23 |
$params = array(); |
24 |
$limit_per_page = 1; |
25 |
$start_index = ($this->uri->segment(3)) ? $this->uri->segment(3) : 0; |
26 |
$total_records = $this->Users->get_total(); |
27 |
|
28 |
if ($total_records > 0) |
29 |
{
|
30 |
// get current page records
|
31 |
$params["results"] = $this->Users->get_current_page_records($limit_per_page, $start_index); |
32 |
|
33 |
$config['base_url'] = base_url() . 'paging/index'; |
34 |
$config['total_rows'] = $total_records; |
35 |
$config['per_page'] = $limit_per_page; |
36 |
$config["uri_segment"] = 3; |
37 |
|
38 |
$this->pagination->initialize($config); |
39 |
|
40 |
// build paging links
|
41 |
$params["links"] = $this->pagination->create_links(); |
42 |
}
|
43 |
|
44 |
$this->load->view('user_listing', $params); |
45 |
}
|
46 |
|
47 |
public function custom() |
48 |
{
|
49 |
// load db and model
|
50 |
$this->load->database(); |
51 |
$this->load->model('Users'); |
52 |
|
53 |
// init params
|
54 |
$params = array(); |
55 |
$limit_per_page = 2; |
56 |
$page = ($this->uri->segment(3)) ? ($this->uri->segment(3) - 1) : 0; |
57 |
$total_records = $this->Users->get_total(); |
58 |
|
59 |
if ($total_records > 0) |
60 |
{
|
61 |
// get current page records
|
62 |
$params["results"] = $this->Users->get_current_page_records($limit_per_page, $page*$limit_per_page); |
63 |
|
64 |
$config['base_url'] = base_url() . 'paging/custom'; |
65 |
$config['total_rows'] = $total_records; |
66 |
$config['per_page'] = $limit_per_page; |
67 |
$config["uri_segment"] = 3; |
68 |
|
69 |
// custom paging configuration
|
70 |
$config['num_links'] = 2; |
71 |
$config['use_page_numbers'] = TRUE; |
72 |
$config['reuse_query_string'] = TRUE; |
73 |
|
74 |
$config['full_tag_open'] = '<div class="pagination">'; |
75 |
$config['full_tag_close'] = '</div>'; |
76 |
|
77 |
$config['first_link'] = 'First Page'; |
78 |
$config['first_tag_open'] = '<span class="firstlink">'; |
79 |
$config['first_tag_close'] = '</span>'; |
80 |
|
81 |
$config['last_link'] = 'Last Page'; |
82 |
$config['last_tag_open'] = '<span class="lastlink">'; |
83 |
$config['last_tag_close'] = '</span>'; |
84 |
|
85 |
$config['next_link'] = 'Next Page'; |
86 |
$config['next_tag_open'] = '<span class="nextlink">'; |
87 |
$config['next_tag_close'] = '</span>'; |
88 |
|
89 |
$config['prev_link'] = 'Prev Page'; |
90 |
$config['prev_tag_open'] = '<span class="prevlink">'; |
91 |
$config['prev_tag_close'] = '</span>'; |
92 |
|
93 |
$config['cur_tag_open'] = '<span class="curlink">'; |
94 |
$config['cur_tag_close'] = '</span>'; |
95 |
|
96 |
$config['num_tag_open'] = '<span class="numlink">'; |
97 |
$config['num_tag_close'] = '</span>'; |
98 |
|
99 |
$this->pagination->initialize($config); |
100 |
|
101 |
// build paging links
|
102 |
$params["links"] = $this->pagination->create_links(); |
103 |
}
|
104 |
|
105 |
$this->load->view('user_listing', $params); |
106 |
}
|
107 |
}
|
Далее нам понадобится модель в файле models/Users.php
, которая извлекает записи из таблицы users.
1 |
<?php
|
2 |
// models/Users.php
|
3 |
defined('BASEPATH') OR exit('No direct script access allowed'); |
4 |
|
5 |
class Users extends CI_Model |
6 |
{
|
7 |
function __construct() |
8 |
{
|
9 |
parent::__construct(); |
10 |
}
|
11 |
|
12 |
public function get_current_page_records($limit, $start) |
13 |
{
|
14 |
$this->db->limit($limit, $start); |
15 |
$query = $this->db->get("users"); |
16 |
|
17 |
if ($query->num_rows() > 0) |
18 |
{
|
19 |
foreach ($query->result() as $row) |
20 |
{
|
21 |
$data[] = $row; |
22 |
}
|
23 |
|
24 |
return $data; |
25 |
}
|
26 |
|
27 |
return false; |
28 |
}
|
29 |
|
30 |
public function get_total() |
31 |
{
|
32 |
return $this->db->count_all("users"); |
33 |
}
|
34 |
}
|
Наконец, давайте создадим файл представления views/user_listing.php
, который отобразит список пользователей.
1 |
<!-- views/user_listing.php -->
|
2 |
<html>
|
3 |
<head>
|
4 |
<title>Paging Example-User Listing</title> |
5 |
</head>
|
6 |
|
7 |
<body>
|
8 |
<div class="container"> |
9 |
<h1 id='form_head'>User Listing</h1> |
10 |
|
11 |
<?php if (isset($results)) { ?> |
12 |
<table border="1" cellpadding="0" cellspacing="0"> |
13 |
<tr>
|
14 |
<th>ID</th> |
15 |
<th>NAME</th> |
16 |
</tr>
|
17 |
|
18 |
<?php foreach ($results as $data) { ?> |
19 |
<tr>
|
20 |
<td><?php echo $data->uid ?></td> |
21 |
<td><?php echo $data->uname ?></td> |
22 |
</tr>
|
23 |
<?php } ?> |
24 |
</table>
|
25 |
<?php } else { ?> |
26 |
<div>No user(s) found.</div> |
27 |
<?php } ?> |
28 |
|
29 |
<?php if (isset($links)) { ?> |
30 |
<?php echo $links ?> |
31 |
<?php } ?> |
32 |
</div>
|
33 |
</body>
|
34 |
</html>
|
Теперь перейдите к нашей пользовательской странице по адресу http://your-code-igniter-site/paging/index, и вы должны увидеть список пользователей вместе с разбиением на страницы! Так вот, мы это сделали! Не волнуйтесь, я не оставлю вас так сразу, так как мы сейчас начнем подробно рассматривать каждую часть кода.
Мы начнем с файла модели models/Users.php
, так как она будет вызываться из наших методов контроллера. Существуют два важных метода: get_current_page_records
и get_total
, которые наша модель реализует для создания ссылок на страницы.
Давайте рассмотрим метод get_total
. Он используется для подсчета количества записей в таблице пользователей.
1 |
public function get_total() |
2 |
{
|
3 |
return $this->db->count_all("users"); |
4 |
}
|
Далее, есть метод get_current_page_records
.
1 |
public function get_current_page_records($limit, $start) |
2 |
{
|
3 |
$this->db->limit($limit, $start); |
4 |
$query = $this->db->get("users"); |
5 |
|
6 |
if ($query->num_rows() > 0) |
7 |
{
|
8 |
foreach ($query->result() as $row) |
9 |
{
|
10 |
$data[] = $row; |
11 |
}
|
12 |
|
13 |
return $data; |
14 |
}
|
15 |
|
16 |
return false; |
17 |
}
|
Есть два важных аргумента, которые вы должны отметить в методе get_current_page_records
. Первый аргумент $limit
используется для указания количества записей, которые будут возвращены во время выполнения запроса. И второй аргумент, $start
, действует как начальный индекс записи.
Итак, как вы можете видеть, с учетом значений $start
и $limit
мы можем получать записи по страницам. В этом суть пагинации, и между тем мы внедрили самый важный метод этой статьи!
Итак, это была наша модель - простая и элегантная!
Двигаясь вперед, давайте переключим внимание на файл контроллера. Идем дальше и рассмотрим код метода конструктора.
1 |
public function __construct() |
2 |
{
|
3 |
parent::__construct(); |
4 |
|
5 |
// load Pagination library
|
6 |
$this->load->library('pagination'); |
7 |
|
8 |
// load URL helper
|
9 |
$this->load->helper('url'); |
10 |
}
|
Чтобы использовать разбиение на страницы в CodeIgniter, первое, что вам нужно сделать, это загрузить библиотеку пагинации. И мы можем это сделать, используя $this->load->library('pagination')
.
Мы также загрузили хелпер URL, чтобы мы могли использовать глобальные вспомогательные функции, предоставляемые этим помощником.
Теперь мы готовы пройти через сердце нашего контроллера - метод index
.
1 |
public function index() |
2 |
{
|
3 |
// load db and model
|
4 |
$this->load->database(); |
5 |
$this->load->model('Users'); |
6 |
|
7 |
// init params
|
8 |
$params = array(); |
9 |
$limit_per_page = 1; |
10 |
$start_index = ($this->uri->segment(3)) ? $this->uri->segment(3) : 0; |
11 |
$total_records = $this->Users->get_total(); |
12 |
|
13 |
if ($total_records > 0) |
14 |
{
|
15 |
// get current page records
|
16 |
$params["results"] = $this->Users->get_current_page_records($limit_per_page, $start_index); |
17 |
|
18 |
$config['base_url'] = base_url() . 'paging/index'; |
19 |
$config['total_rows'] = $total_records; |
20 |
$config['per_page'] = $limit_per_page; |
21 |
$config["uri_segment"] = 3; |
22 |
|
23 |
$this->pagination->initialize($config); |
24 |
|
25 |
// build paging links
|
26 |
$params["links"] = $this->pagination->create_links(); |
27 |
}
|
28 |
|
29 |
$this->load->view('user_listing', $params); |
30 |
}
|
Для начала убедитесь, что база данных настроена правильно. После этого мы загружаем модель Users
, чтобы мы могли использовать методы модели.
1 |
$this->load->database(); |
2 |
$this->load->model('Users'); |
Затем мы инициализируем пару важных переменных.
1 |
// init params
|
2 |
$params = array(); |
3 |
$limit_per_page = 1; |
4 |
$start_index = ($this->uri->segment(3)) ? $this->uri->segment(3) : 0; |
5 |
$total_records = $this->Users->get_total(); |
Переменная $limit_per_page
определяет предел на страницу. Конечно, вы могли бы установить его, какой хотите; на данный момент он установлен на 1, для целей примера.
Переменная $start_index
содержит начальный индекс записи MySQL. Когда CodeIgniter создает ссылки для разбивки на страницы, он добавляет начальный индекс страницы в качестве третьего сегмента в URL по умолчанию. Вы можете изменить это поведение по умолчанию, но это то, что мы зарезервируем для последнего раздела этой статьи, где мы обсудим параметры настройки.
Наконец, мы вызываем метод get_total
модели Users для получения общих записей таблицы пользователей и присваиваем переменной $total_records
.
Затем мы извлекаем записи текущей страницы с использованием метода get_current_page_records
.
1 |
// get current page records
|
2 |
$params["results"] = $this->Users->get_current_page_records($limit_per_page, $start_index); |
Прежде чем мы сможем фактически продолжить создание ссылок на страницы, нам нужно инициализировать минимальную конфигурацию поискового вызова, используя метод initialize
библиотеки пагинации.
1 |
$config['base_url'] = base_url() . 'paging/index'; |
2 |
$config['total_rows'] = $total_records; |
3 |
$config['per_page'] = $limit_per_page; |
4 |
$config["uri_segment"] = 3; |
5 |
|
6 |
$this->pagination->initialize($config); |
И это набор минимальных параметров для создания ссылок на страницы.
- base_url: URL-адрес, который будет использоваться при создании ссылок на страницы.
- total_rows: Общее количество записей
- per_page: количество записей на странице
Наконец, мы используем метод create_links
для создания ссылок на страницы.
1 |
// build paging links
|
2 |
$params["links"] = $this->pagination->create_links(); |
Остальное - это просто формальность, чтобы вызвать наше отображение user_listing
и отобразить результат! Откройте URL http://your-code-igniter-site/paging/index, чтобы просмотреть список пользователей вместе с ссылками на страницы.
Итак, это очень простой, но полезный пример pagination в вашем распоряжении, который вы можете расширить в соответствии с вашими требованиями.
В следующем разделе мы рассмотрим, как можно настроить разбивку по умолчанию с точки зрения внешнего вида и функциональности.
Исследуем параметры настройки
В этом разделе мы рассмотрим доступные варианты, которые вы можете использовать, если хотите настроить ссылки для разбивки по страницам по умолчанию.
Сегмент URI
Хотя библиотека пагинации CodeIgniter автоматически определяет параметр связанный с пагинацией из URL-адреса, вы можете определить пользовательское значение, если у вас есть другой шаблон URL.
1 |
$config["uri_segment"] = 4; |
Количество цифровых ссылок
Параметр num_links
позволяет вам определить количество цифровых ссылок, которые будут отображаться до и после номера активной страницы в ссылках на страницы.
1 |
$config['num_links'] = 2; |
Номер страницы как сегмент URI
Когда вы получаете доступ к сегменту URI пагинации, по умолчанию он является начальным индексом. Например, если у вас есть десять записей на странице, сегмент URI пагинации составляет 20 для третьей страницы. Вместо этого, если вы хотите показать фактические номера страниц в ссылках, вы можете установить use_page_numbers
в значение TRUE
.
1 |
$config['use_page_numbers'] = TRUE; |
Конечно, вам нужно убедиться, что вы подсчитали правильный начальный индекс на основе номера страницы, которую вы извлекаете из URL-адреса.
Сохранять строку запроса
Чаще всего вы оказываетесь в ситуации, когда хотите сохранить параметры строки запроса, которые не связаны с разбиением на страницы. Вы можете использовать параметр reuse_query_string
, чтобы включить этот объект.
1 |
$config['reuse_query_string'] = TRUE; |
Это были несколько вариантов, которые вы могли бы использовать для изменения функциональности пагинации по умолчанию. Затем мы рассмотрим несколько других параметров, которые позволят вам изменить способ отображения ссылок на страницы.
Тег обертки
Если вы хотите обернуть код разбивки на страницы любым другим тегом HTML, вы можете сделать это, используя опции full_tag_open
и full_tag_close
.
1 |
$config['full_tag_open'] = '<div class="pagination">'; |
2 |
$config['full_tag_close'] = '</div>'; |
Это может быть очень полезно, если вы захотите применить пользовательский стиль к ссылкам на страницы.
Первый, последний, следующий и предыдущий
Если вы хотите изменить текст, который будет отображаться для первой, последней, следующей и предыдущей ссылок, вы также можете это сделать.
1 |
$config['first_link'] = 'First Page'; |
2 |
$config['last_link'] = 'Last Page'; |
3 |
$config['next_link'] = 'Next Page'; |
4 |
$config['prev_link'] = 'Prev Page'; |
Кроме того, если вы хотите обернуть эти отдельные ссылки любым HTML-тегом, вы можете сделать это так же, как мы это сделали, чтобы обернуть весь код поискового вызова.
1 |
$config['first_tag_open'] = '<span class="firstlink">'; |
2 |
$config['first_tag_close'] = '</span>'; |
3 |
|
4 |
$config['last_tag_open'] = '<span class="lastlink">'; |
5 |
$config['last_tag_close'] = '</span>'; |
6 |
|
7 |
$config['next_tag_open'] = '<span class="nextlink">'; |
8 |
$config['next_tag_close'] = '</span>'; |
9 |
|
10 |
$config['prev_tag_open'] = '<span class="prevlink">'; |
11 |
$config['prev_tag_close'] = '</span>'; |
Активная ссылка и номер ссылки
Иногда вы хотите по-разному настраивать активную ссылку. Вы можете сделать это, применив теги-оболочки, как показано ниже.
1 |
$config['cur_tag_open'] = '<span class="curlink">'; |
2 |
$config['cur_tag_close'] = '</span>'; |
Точно так же, если вы хотите связать цифру с чем-то:
1 |
$config['num_tag_open'] = '<span class="numlink">'; |
2 |
$config['num_tag_close'] = '</span>'; |
На этом наша история настройки заканчивается. Фактически, вы можете пойти дальше и посмотреть пример настройки в http://your-code-igniter-site/paging/custom, который уже включен в наш файл контроллера!
Настройка пагинации
Теперь вы знаете о конфигурации, которая необходима для создания достойной разбивки на страницы с любым списком моделей. И большую часть времени вы хотите сохранить его на всем сайте. Что вы собираетесь сделать для этого? Возможно, у вас возникнет соблазн скопировать код конфигурации и вставить его в каждое действие, требующее настройки разбиения на страницы.
Фактически, есть лучший способ справиться с этим сценарием. Вы можете создать файл конфигурации пагинации в файле application/config/pagination.php
и использовать переменную $config
для определения ваших настроек.
1 |
<?php
|
2 |
$config['per_page'] = 10; |
3 |
$config["uri_segment"] = 3; |
4 |
|
5 |
$config['full_tag_open'] = '<div class="pagination">'; |
6 |
$config['full_tag_close'] = '</div>'; |
7 |
|
8 |
$config['first_link'] = 'First Page'; |
9 |
$config['first_tag_open'] = '<span class="firstlink">'; |
10 |
$config['first_tag_close'] = '</span>'; |
11 |
|
12 |
$config['last_link'] = 'Last Page'; |
13 |
$config['last_tag_open'] = '<span class="lastlink">'; |
14 |
$config['last_tag_close'] = '</span>'; |
15 |
|
16 |
$config['next_link'] = 'Next Page'; |
17 |
$config['next_tag_open'] = '<span class="nextlink">'; |
18 |
$config['next_tag_close'] = '</span>'; |
19 |
|
20 |
$config['prev_link'] = 'Prev Page'; |
21 |
$config['prev_tag_open'] = '<span class="prevlink">'; |
22 |
$config['prev_tag_close'] = '</span>'; |
23 |
|
24 |
$config['cur_tag_open'] = '<span class="curlink">'; |
25 |
$config['cur_tag_close'] = '</span>'; |
26 |
|
27 |
$config['num_tag_open'] = '<span class="numlink">'; |
28 |
$config['num_tag_close'] = '</span>'; |
Исходя из этого, пересмотренный метод действия index
должен выглядеть следующим образом:
1 |
public function index() |
2 |
{
|
3 |
// load db and model
|
4 |
$this->load->database(); |
5 |
$this->load->model('Users'); |
6 |
|
7 |
// init params
|
8 |
$params = array(); |
9 |
$start_index = ($this->uri->segment(3)) ? $this->uri->segment(3) : 0; |
10 |
$total_records = $this->Users->get_total(); |
11 |
|
12 |
// load config file
|
13 |
$this->config->load('pagination', TRUE); |
14 |
$settings = $this->config->item('pagination'); |
15 |
$settings['total_rows'] = $this->Users->get_total(); |
16 |
$settings['base_url'] = base_url() . 'paging/config'; |
17 |
|
18 |
if ($total_records > 0) |
19 |
{
|
20 |
// get current page records
|
21 |
$params["results"] = $this->Users->get_current_page_records($settings['per_page'], $start_index); |
22 |
|
23 |
// use the settings to initialize the library
|
24 |
$this->pagination->initialize($settings); |
25 |
|
26 |
// build paging links
|
27 |
$params["links"] = $this->pagination->create_links(); |
28 |
}
|
29 |
|
30 |
$this->load->view('user_listing', $params); |
31 |
}
|
Конечно, переменные total_rows
и base_url
изменяются от действия к действию, поэтому вам нужно явно указывать их в каждом действии.
Для этого вам необходимо сначала загрузить конфигурацию разбиения на страницы.
1 |
$this->config->load('pagination', TRUE); |
2 |
$settings = $this->config->item('pagination'); |
Затем вы можете переопределить определенные действия.
1 |
$settings['total_rows'] = $this->Users->get_total(); |
2 |
$settings['base_url'] = base_url() . 'paging/config'; |
И на этом мы закончим!
Итак, это была история конфигурации пагинации, и на этом также заканчивается наша статья!
Заключение
Сегодня мы рассмотрели библиотеку разбиения на страницы в CodeIgniter.
В первой части этой статьи я продемонстрировал, как вы можете использовать библиотеку разбиения на страницы, предоставляя очень простой, но полезный пример.
После этого мы обсудили параметры настройки, которые есть в вашем распоряжении, при настройке разбивки на страницы.
Наконец, в последнем разделе мы обсудили конфигурацию разбиения на страницы.
CodeIgniter - мощная платформа PHP. Если вы только начинаете его изучать, не забудьте проверить, что у нас есть для вас.
Я хотел бы узнать ваши отзывы в форме запросов и комментариев, используя приведенный ниже канал!