Постраничный вывод большого количества записей

Задача
Необходимо отобразить на странице большой набор данных и обеспечить ссылки, позволяющие перемещаться по этому набору данных.

Решение
Здесь нужен PEAR класс DB_Pager:

require 'DB/Pager.php';
$offset = intval($_REQUEST['offset']);
$per_page = 3;
$sth = $dbh->query('SELECT * FROM zodiac ORDER BY id');
$pager = new DB_Pager($sth, $offset, $per_page);
$data = $pager->build();
// выводим на эту страницу каждую строку
while ($v = $pager->fetchRow()) {
print "$v->sign, $v->symbol ($v->id)
";
}
// ссылка на предыдущую страницу
printf('<<Prev |',
$_SERVER['PHP_SELF'],$data['prev']);
// прямая ссылка на каждую страницу
foreach ($data['pages'] as $page => $start) {
printf(' %d
|',$_SERVER['PHP_SELF'],$start,$page);
}
// ссылка на следующую страницу
printf(' Next>>',
$_SERVER['PHP_SELF'],$data['next']);
// показываем, какие записи находятся на данной странице
printf("
(Displaying %d - %d of %d)",
$data['from'],$data['to'],$data['numrows']);

Если класса DB_Pager нет или вы не хотите его использовать, то можно реализовать свое собственное отображение индексированной ссылки с помощью функций pc_indexed_links() и pc_print_link(), показанных в разделе «Обсуждение» в примерах 10.2 и 10.3.
$offset = intval($_REQUEST['offset']);
if (! $offset) { $offset = 1; }
$per_page = 5;
$total = $dbh->getOne('SELECT COUNT(*) FROM zodiac');
$sql = $dbh->modifyLimitQuery('SELECT * FROM zodiac ORDER BY id',
$offset - 1,$per_page);
$ar = $dbh->getAll($sql);
foreach ($ar as $k => $v) {
print "$v->sign, $v->symbol ($v->id)
";
}
pc_indexed_links($total,$offset,$per_page);
printf("
(Displaying %d - %d of %d)",$offset,$offset+$k,$total);

Обсуждение
Класс DB_Pager разработан специально для постраничного отображения результатов запроса PEAR DB.


Для того чтобы его использовать, создайте объект класса DB_Pager и укажите ему, какой запрос послать, какое смещение задать в начале результирующего множества, и какое количество элементов должно находиться на каждой странице. Это
обеспечит корректное размещение информации по страницам.

Метод $pager->build() определяет возвращаемые строки и другие переменные, необходимые для конкретной страницы. Класс DB_Pager предоставляет метод fetchRow() для извлечения результатов, который работает таким же образом, как метод класса DB. (В классе DB_Pager можно также использовать метод fetchInto()). Однако, хоть он и предоставляет всю необходимую информацию для построения соответствующих
ссылок, но оставляет вам собственно разработку этих ссылок. Начальное смещение предыдущей страницы находится в переменной $data['prev'], а переменная $data['next'] содержит начальное смещение следующей страницы. Массив $data['pages'] хранит номера страниц и их начальные смещения. Вывод для случая, когда переменная $offset
равна 0.

Все номера страниц, а также «<>» представляют собой ссылки. «<


На странице 4 ссылка «Next>>» указывает обратно на страницу 1. (Но ссылка
«<
Если класс DB_Pager недоступен, то получить соответствующим образом отформатированные ссылки позволяют функции pc_print_link()
и pc_indexed_links(), показанные в примерах 10.2 и 10.3.
Пример 10.2. pc_print_link()
function pc_print_link($inactive,$text,$offset='') {
if ($inactive) {printf('%s',$text);
} else {
printf('%s a>',$_SERVER['PHP_SELF'],$offset,$text);
}
}
Пример 10.3. pc_indexed_links()
function pc_indexed_links($total,$offset,$per_page) {
$separator = ' | ';
// выводим ссылку "< pc_print_link($offset == 1, '<<Prev', $offset - $per_page);
// выводим все группировки, за исключением последней
for ($start = 1, $end = $per_page;
$end < $total;
$start += $per_page, $end += $per_page) {
print $separator;
pc_print_link($offset == $start, "$start-$end", $start);
}
/* выводим последнюю группировку - в этой точке переменная $start
* указывает на элемент в начале последней группировки
*/
/* текст толжен содержать диапазон, только если на последней
* странице находится более одного элемента.


Например,
* последняя группировка из 11 элементов по 5 на каждой
* странице должна показать просто "11", а не "11-11"
*/
$end = ($total > $start) ? "-$total" : '';
print $separator;
pc_print_link($offset == $start, "$start$end", $start);
// выводим ссылку "Next>>"
print $separator;
pc_print_link($offset == $start, 'Next>>',$offset + $per_page);
}

Применяя эти функции, извлеките соответствующее подмножество данных с помощью метода DB::modifyLimitQuery() и выведите их. Для отображения индексированных ссылок вызовите функцию pc_indexed_links():

$offset = intval($_REQUEST['offset']);
if (! $offset) { $offset = 1; }
$per_page = 5;
$total = $dbh->getOne('SELECT COUNT(*) FROM zodiac');
$sql = $dbh->modifyLimitQuery('SELECT * FROM zodiac ORDER BY id',
$offset - 1,$per_page);
$ar = $dbh->getAll($sql);foreach ($ar as $k => $v) {
print "$v->sign, $v->symbol ($v->id)
";
}
pc_indexed_links($total,$offset,$per_page);
printf("
(Displaying %d - %d of %d)",$offset,$offset+$k,$total);

После соединения с базой данных необходимо убедиться, что переменная $offset имеет соответствующее значение. Переменная $offset представляет начальную запись в результирующем множестве, которое
требуется отобразить. Чтобы стартовать с начала результирующего набора данных, надо установить переменную $offset в 1. В переменную $per_page заносится количество записей, отображаемых на каждой странице, а переменная $total представляет общее количество записей во всем результирующем множестве. В данном примере показываются
все записи из таблицы Zodiac, поэтому переменной $total присваивается количество всех строк в таблице.

SQL-запрос, извлекающий данные в соответствующем порядке, имеет вид:

SELECT * FROM zodiac ORDER BY id

Для ограничения извлекаемых строк вызовите функцию modifyLimitQuery(). Чтобы извлечь $per_page строк, надо начинать с $offset - 1, поскольку первая строка в базе данных имеет номер 0, а не 1. Для ограничения строк, возвращаемых запросом, метод modifyLimitQuery()
реализует корректный алгоритм, специфический для конкретной базы данных.

Выбранные строки извлекаются с помощью метода $dbh->getAll($sql), а затем отображается информация, содержащаяся в каждой строке. В конце каждой строки функция предоставляет навигационные ссылки. Вывод для случая, когда переменная $offset не установлена (или равна 1).На рис. 10.4 «6-10», «11-12» и «Next>>» представляют собой ссылки на одну и ту же страницу с заданными аргументами $offset, тогда как «< в настоящее время отображается.

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела PHP на эту тему:
Автоматическое присваивание уникальных значений идентификаторов
Выполнение запросов к базе данных SQL
Извлечение строк без цикла
Кэширование запросов и результатов
Модификация данных в базе данных SQL

Вернуться в раздел: PHP / 10. Доступ к базам данных