Организация страничного вывода средствами MySQL и PHP

При работе с данными часто бывает нужно организовать навигацию по списку. Таким списком может быть результат поиска или просто выборка данных из большой таблицы.

Чтобы разбить список на страницы, нужно выполнить нехитрый математический расчёт. А именно, поделить общее число найденных записей на количество записей, которое нужно получить на одной странице.

Если с количеством записей на странице всё более или менее ясно, то с общим числом найденных записей обычно возникают проблемы. Однако, в MySQL, начиная с четвёртой версии и выше, появилась функция FOUND_ROWS(), которая позволяет узнать общее количество найденных записей, даже если в выборке использовалось ограничение с помощью LIMIT.

Официальное руководство по использованию FOUND_ROWS() находится по адресу http://dev.mysql.com/doc/refman/4.1/en/information-functions.html#function_found-rows.

Следующий код занимается тем, что выводит список записей из базы данных по 10 штук на страницу:

Код - Пример организации страничного вывода средствами MySQL и PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<?php

// Подключение к базе данных
mysql_connect('localhost', 'root') || die('Can\'t connect to database');

// Объявляем кодировки для правильной работы
mysql_query('SET names "utf8"');
header('Content-Type: text/html; charset=UTF-8');

// Текущая страница
$cur_page = isset($_GET['page']) ? (int) $_GET['page'] : 0;

// Текущая страница не может быть меньше единицы
if ( $cur_page < 1 ) $cur_page = 1;

// Количество записей на странице
$items_per_page = 10;

// Запрос на выборку
$sql = '
SELECT SQL_CALC_FOUND_ROWS 
    * 
    
FROM
    `mysql`.`help_category`
    
LIMIT
    '. (($cur_page - 1) * $items_per_page) .', '. ((int) $items_per_page) .'';

// Исполнение запроса
$res = mysql_query($sql);
if ( !$res ) die('Bad SQL-query: <br /><pre>'. $sql .'</pre><p>'. mysql_error() .'</p>');

// Количество записей, которые вернул запрос
$items_count = mysql_affected_rows();

// Общее количество найденых записей, без учёта лимита
list($total) = mysql_fetch_row(mysql_query('SELECT FOUND_ROWS()'));

// Количество страниц, которое необходимо для просмотра списка
$pages_count = ceil($total / $items_per_page);

// Если страниц больше одной, то необходимо вывести их
if ( $pages_count > 1 )
{
    echo '<p>Страницы: ';
    
    // Поскольку количество страниц заранее известно, то используем for
    for ( $i = 1; $i <= $pages_count; ++$i )
        echo '<a href="?page=', $i, '">', $i, '</a> ';
        
    echo '</p>';
}

// Если были найдены записи, то выводим список
if ( $items_count )
{
    // Список будет нумерованным
    echo '<ol start="', ($cur_page - 1) * $items_per_page + 1 ,'">', PHP_EOL;
    
    // Вывод найденных записей
    while ( $row = mysql_fetch_assoc($res) )
        echo '<li>', htmlentities($row['name'], ENT_QUOTES, 'UTF-8'), '</li>', PHP_EOL;
    
    echo '</ol>';
}
else
{
    // Список пуст, выводить нечего
    echo '<p>К сожалению, нет подходящих записей для просмотра.</p>';
}

?>

Результат будет выглядеть примерно так:

Если есть вопросы или пожелания, пишите сюда, постараюсь ответить :)

Удачных наработок!