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

Давайте рассмотрим задачу как вывести данные из mysql с постраничником. Ниже разобран код простой и универсальной функции для постраничного вывода данных из таблиц MySQL.

Чтобы рассмотреть данный пример, нам понадобится простенькая таблица, например, "articles" в mysql-базе данных, например, "datadb". Структура таблицы данных пусть будет такая:

idarticle
1Статья один
2Два статья
3Три
4Четвертая
5Статья № 5

Для постраничного вывода нам понадобится общее число записей в таблице. Здесь есть простор для творчества: можно организовать сложный запрос в базу данных, который выдаст нам сразу общее число записей и сами данные с такого по такое. Но, имхо, будет проще и правильнее сделать два запроса. Итак, приступим:

Создадим файл "a.php":

<?
// Будем выводить по 2 записи на листе:
$number = 2;
// Читаем сдвиг из GET-массива:
$offset = isset($_GET['offset']) ? (int)$_GET['offset'] : 0;
// Коннект до базы данных
$link = mysql_connect('localhost', $dbuser, $dbpass);
if (!$link) die('Не могу соединиться с базой данных');
// Выбираем базу данных
mysql_select_db('datadb', $link);
// Выполняем запрос 'посчитать число записей'
$result = mysql_query("SELECT COUNT(*) FROM `articles`", $link);
// Теперь в переменной $total общее число записей
$total = mysql_result($result, 0);
$menu = getMenuofPages($total, $number, $offset);
?>

Теперь нужно написать саму функцию getMenuofPages, получающую на входе общее число записей, число записей для вывода на странице и сдвиг (т. е. начиная с какой записи показывать). Например вот так:

<?
function getMenuofPages($total, $number, $offset) {
   // Подфункция определяет есть ли уже в текущем url get-данные постраничника
   // и дописывает соответственно нужный offset:
   function getGoodUrl($url, $cur) {
      if ($_SERVER['QUERY_STRING'] == "") {
         return $url."?offset=".$cur;
      }else {
         if (substr_count($_SERVER['QUERY_STRING'], "offset=") > 0) {
            $url = preg_replace("/offset=\d+/i", "offset=".$cur, $url);
            return $url;
         }else {
            return $url."&offset=".$cur;
         }
      }
   }
   // Если общее число меньше числа записей, которые мы должны вывести на
   // странице, то ничего не делаем:
   if ($total <= $number) {
      return;
   }
   $url = $_SERVER['REQUEST_URI'];
   $int = intval($total / $number); // Целая часть от деления
   $rest = $total % $number; // Остаток от деления
   $menu = "";
   // Сначала перебираем целые части
   for ($i = 0; $i < $int; $i++) {
      $cur = $i * $number;
      if ($cur == $offset) { // Проверка на текущую страницу
         $menu .= " | ".($cur + 1)."-".($cur + $number);
      }else {
         $menu .= " | <a href=\"".getGoodUrl($url, $cur)."\">".
                  ($cur + 1)."-".($cur + $number)."</a>";
      }
   }
   // Потом остаток (если есть)
   if ($rest > 0) {
      $cur += $number;
      if ($cur == $offset) { // Проверка на текущую страницу
         if ($rest == 1) {
            $menu .= " | ".($cur + 1)." |";
         }else {
            $menu .= " | ".($cur + 1)."-".($cur + $rest)." |";
         }
      }else {
         if ($rest == 1) {
            $menu .= " | <a href=\"".getGoodUrl($url, $cur)."\">".($cur + 1)."</a> |";
         }else {
            $menu .= " | <a href=\"".getGoodUrl($url, $cur)."\">".
                     ($cur + 1)."-".($cur + $rest)."</a> |";
         }
      }
   }else {
      $menu .= " |";
   }
   return $menu;
}
?>

Меню готово, теперь осталось читать из mysql данные в соответствии с offset и number. Так:

<?
// Читаем из базы $number записей начиная с $offset:
$result = mysql_query("SELECT * FROM `articles` LIMIT $offset, $number", $link);
// Распечатываем результат:
echo $menu;
while ($row = mysql_fetch_array($result)) {
   echo '<div>'.$row['id'].' : '.$row['article'].'</div>';
}
?>

Если вы все сделали правильно, у вас должно получиться примерно это:

Постраничный вывод php+mysql

Естественно можно функцию getMenuofPages усовершенствовать, например, подавая ей в аргументах шаблон для вывода ссылок. Можно также дописать ссылки вида "назад" и "вперед". Дерзайте!

Для очень больших объемов данных используют другой подход. В таких таблицах ощутимое время занимает простой mysql-запрос подсчета количества записей в таблице. Поэтому в постраничнике делают только два контрола - вперед и назад, без возможности прокрутки сразу в конец и в самое начало. А также в этом случае мы лишены номеров страниц.

По поводу нумерации страниц в постраничнике, кстати, есть шутка: вы знаете почему на популярных ресурсах (к примеру reddit), нет номеров страниц? По той же причине почему в казино нет часов.

Теги: 

Добавить комментарий

Filtered HTML

  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешённые HTML-теги: <a> <em> <i> <strong> <b> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd> <p> <br>
  • Строки и параграфы переносятся автоматически.

Plain text

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Строки и параграфы переносятся автоматически.
CAPTCHA
CAPTCHA на основе изображений
Введите код с картинки