Простой постраничный вывод данных на php. Постраничный вывод из MySQL

Делаем постраничный вывод на Php + Mysql

В самом начале своего пути веб-программиста знаний у меня как и все было еще очень мало, но желания хоть отбавляй. И вот я начал писать свой первый скрипт - гостевую книгу. В то время интернет только начал зарождаться и гостевая книга была популярна. Но после нескольких дней я столкнулся с проблемой, которую в то время не мог решить: как выводить все сообщения по 10 на странице? С этим было просто, но вот как сделать ссылки на страницы, при переходе на которые показывались бы следующие 10 страниц???

Это было для меня огромной проблемой и для ее решения я оббегал кучу форумов и сайтов. Постраничный вывод очень нужен и в наше время, но статей по нему до сих пор почти нет. Я решил исправить эту несправедливость. На своем примере я покажу вам постраничный вывод сообщений из mysql-базы, т.к. сейчас она очень популярна и имеет множество преимуществ по сравнению с файлами. Если вам будет нужно, то я могу показать вам постраничный вывод сообщений из файла.

Сначала надо пределить с базой, в которой хранятся наши сообщения. Не будем придумывать огромные базы с сотнями таблиц. Возьмем для примера такую базу, в которой только только 1 таблица и в ней 2 поля: номер сообщения и само сообщение. Чуть ниже вы можете посмотреть на структуру таблицы из этой базы.

id text
1 text1
2 text2
3 text3
4 text4
5 text5

С базой определились, можно начинать скрипт. Для начала подключимся к нашей новоиспеченной базе и вычислим число строк в таблице posts.
$link = mysql_connect("localhost","user","pass"); //Подключаемся к серверу базы данных
mysql_select _db("base",$link); //Выбираем базу
$posts = mysql_query("select * from posts");
$total_posts = mysql_num_rows($posts); //Считаем число строк в таблице с сообщениями (posts)

Итак, начало положено. Теперь будем писать функцию для отображения ссылок на другие страницы с сообщениями, собственно говоря сам постраничный вывод. Это не слишком сложная функция, но и не самая простая, т.к. меньше она быть не должна, а больше по вашему усмотрению. Мы задаем функции 4 аргумента (в комментарии они описаны). Вы можете добавить несколько примочек в эту функцию на свой вкус я дал вам лишь основу, дальше двигайтесь сами. Можно например выделить ссылку на текущую страничку.

function print_links($total,$page,$number,$links) //1 аргумент - всего сообщений, 2 - номер текущей страницы, 3 - число сообщений на странице, 4 - число отображаемых ссылок
{
$return = null;
$pages = ceil($total/$number); //Вычисляем сколько должно получиться страниц

if ($page+$links <= $pages)
{
$start = $page;
}
else
{
$start = $pages-($links-1);
$finish = $pages;
}

if ($start < 0)
{
$start = 1;
}

for ($i=$start;$i<=$finish;$i++) //Записываем в переменную ссылки
{
$return .= " ".$i." ";
}
return $return; }

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

Для начала добавим небольшую проверку. Если у вас не указан номер страницы, то по умолчанию вам будет отображаться первая страница. МОжно добавить также дополнительные проверки, чтобы исключить работу скрипта при запросах вида: $#$## или фав1324. Это повысит безопасность скрипта, а следовательно и сайта.

if (!isset($page)) { $page = "1"; } //Здесь мы делаем проверку. Если переменная page (номер страницы) не указана, то ей присваивается значение 1
print print_links($total_posts,$page,"10","5"); //Выводим в браузер ссылки
$query = mysql_query("select * from posts limit ".(($page-1)*10).",10 "); //Выбираем нужное число сообщений
while ($row=mysql_fetch_array($guest)) { print "
".$row["text"]."
"; //Выводим сообщения (дизайн делайте сами) }
mysql_close($link);
?>

Вот теперь все. Я показал вам все функции: для генерации ссылок, для вывода сообщений, для подключения к базе, остальное в вашим руках. Если вам интересно будет как сделать постраничный вывод на файлах, то пишите мне и я напишу статью, чтобы всем было понятно.

Если что-то непонятно, то заходите ко мне на сайт или пишите мне на email





Регулярно в форуме задают один и тот же вопрос: как сделать постраничный вывод. И каждый раз человеку отвечают: "Легко! m строк, начиная с n-ной: Select запрос Limit $n,$m". На самом деле не так всё просто.

Я уже писал про синтаксис параметра LIMIT, однако, без толку. Для полноценного постраничного вывода строк из базы требуется большее. Требуется


  • Обработать номер страницы (в том числе проверить, не больше ли он общего количества страниц)
  • Нарисовать навигационную строку (чтобы не просто "вперед-назад", а с ссылками на несколько соседних страниц)

Тут-то и начинаются главные проблемы.

Недавно я работал над сайтом, в котором эти постраничные выводы в статистике были в каждом списке (а списков было много!). Тут-то и созрело решение, как свести все эти штучки к простому и единому решению. Получились четыре функции, которые я теперь использую везде, где нужен постраничный вывод данных, и не напрягаю попусту голову проблемой (как же я делал это там, как бы вынуть этот код оттуда?).

Первая функция — для внутреннего пользования двумя следующими. Берёт номер страницы, общее количество строк и количество строк на странице и выдаёт номер страницы, уже проверенный. Вторая берёт то же самое, проверяет номер страницы и выдаёт парамерт LIMIT либо полный (LIMIT n,m), либо краткий (LIMIT m), если это первая страница, либо ничего не выдаёт. Третья функция из тех же трёх параметров и адреса для ссылки делает навигационную строку. Ещё одна функция выдаёт число для нумерованного списка.

Этого достаточно для нормальной работы с постраничным выводом данных. Посмотрим, что получается в коде программы:


// кол-во строк в страницах

$in_page = 10 ;

// получаем количество строк

$amount = @ mysql_result (mysql_query ("SELECT count(id) as goods_total FROM goods" ), 0 );

// рисуем навигационную строку и пишем начало таблицы

Print("

" . < b > draw_bar ($page , $amount , $in_page ,

"goods.php?page=" ). "

\n" );

// формируем запрос к базе

$goods_result = mysql_query ("SELECT id, name, description, price FROM goods

ORDER BY name, price " . < b > get_limit ($page , $amount , $in_page ));

// получаем номер для нумерованного списка

$count = < b > get_count_limit ($page , $amount , $in_page );

// выводим строки

While ($good_row = mysql_fetch_array ($goods_result )) {

$count ++;

Print ("

// фон каждой второй строки — серым цветом

If ($count / 2 == intval ($count / 2 ))

Print (" bgcolor=#e1e1e1" );

Print (">

\n" );

// конец таблицы и нижняя навигационная строка

Print("

$count.${good_row}


${good_row}

${good_row}
" . < b > draw_bar ($page , $amount ,

$in_page , "goods.php?page=" ). "

\n" );

Это ВСЁ, что нужно для постраничного вывода! Больше напрягаться не надо!

Одно только пояснение — в качестве параметра функции draw_bar указывается адрес этого скрипта со всеми параметрами так, чтобы он туда только дописывал номер страницы. Если сложная выборка, надо будет ручками формировать этот адрес (всё-таки упрощение жизни вышло относительное: упрощаем одно — усложняем другое).

Навигационная панель сделана в виде номеров страниц (" 1 | 2 | 3 "). Но привести к виду "0-10 | 11-20 | 21-30" не проблема.

Половина второго ночи, несколько дней недосыпа... И вдруг озарение - наконец-то я понял, какой-такой супер-пупер скрипт мне нужен для раскрутки моего нового сайта. Сказано - сделано, сажусь... нет не писать этот супер-пупер скрипт:) Программисты народ ленивый, спецы по раскрутке тем более (отсюда и баннерообменные сети, авторегистраторы в каталогах и пр. лентяйские штучки). В общем лезу на Google и начинаю методично обшаривать Рунет в поисках требуемого. Проходит час, два... В душу закрадываются смутные подозрения, плавно перерастающие в уверенность, что требуемый мне скрипт в природе либо не существует, либо спрятан на чьем-то заповедном локалхосте с правами доступа 000.

Разбиваю стоящую перед скриптом задачу на несколько составных и минут за 15 пишу реализацию большинства его (скрипта) функций:) Радостно берусь за следующую фичу... В общем, необходимо всего-то навсего обеспечить постраничный вывод контента. То есть, например, имеется 60 статей и нужно эти статьи выводить по 10 на страницу и построить меню для оного вывода в виде "1 2 3 ..."

Четыре утра, окромя заветного "LIMIT" в голову ничего не приходит. И дело даже не в том, что БД к моему скрипту никакого отношения не имеет. С горечью понимаю, что квалификация потеряна, лучшие годы жизни прожиты впустую и... иду на Google ;)
После... в общем уже наступил рассвет. К этому времени я познакомился с кучей литературы по данному вопросу, но везде ситуация так или иначе рассматривалась в контексте работы с SQL, либо я постоянно наталкивался на какую-то растиражированно-заумную статью про "отделение алгоритма постраничного вывода от контекста или-что-то-в-этом-роде" (ИМХО, нижеприведенные 7 строчек кода эту проблему решают) в которой ничегошеньки не понял... :(И вот когда я уже отчаялся и решил что утро вечера мудренее, на каком-то дремучем, заросшим мхом форуме (адрес к сожалению канул в Лету - по крайней мере у меня его нет), наткнулся на переписку некоего вечно извиняюшегося Программера и безумного и злобного Модератора - тема переписки была посвящена именно построению меню для постраничного вывода. И это было именно то что нужно!

В общем, ниже по тексту я исправляю несправедливость: теперь в Интернете есть статья о том, как обеспечить построение меню для постраничного вывода! Простой рабочий код на PHP, с подробными комментариями. Никакой излишней функциональности типа ссылок "next page". Сделано сие намеренно - ни разу в жизни не нажимал на "next" если можно было нажать на номер страницы - а данная статья написана с целью дать возможность понять основной принцип, т.е. чем меньше кода, тем лучше (хотя кнопка "next" и добавляется тремя строками кода).

Соглашения о комментариях к коду:

  • "Статья" - это некий целостный блок данных (не обязательно текстовых) который и выводится по несколько штук на страницу (это могут быть статьи, новости, картинки и пр.)
  • "Страница" - это страница:) на которой расположено некоторое количество "статей".

Таким образом, на экране браузера мы получили что-то вроде "1 2 3 4 5 6 7 8", при этом URL (на моем компьютере, при выбранной третьей "странице") выглядит так: http://localhost/ep/ep.php?from=20 . Обратите внимание, на то, что странице под номером "3" соответствует значение from=20 то есть отсчет выводимых статей будет вестись в данном случае с 20-й.

Вообще, как вы уже поняли, переменная $from играет здесь ключевую роль. Она участвует в построении ссылок на каждую отдельную страницу (если, конечно, можно так выразиться:), и самое главное - дает нам точку отсчета для вывода статей. Например (и наверняка вы сделаете именно так) указатели на статьи (или сами статьи;) можно поместить в массив, с последующей выборкой и выводом в браузер по 10 статей, начиная от значения $from.

То есть еще раз иными словами: весь огород собственно и городился ради того, чтобы дать скрипту данные относительно того на какой "странице" сейчас находится посетитель и начиная с какого номера "статьи" следует вывести заданное количество этих статей на страницу - а это и есть значение переменной $from. Т.е. при $from=20 выведутся страницы с 21 по 30 (это также зависит от реализации вывода и значения переменной $articles_per_page)

Итак, вы много раз видели, как дынные выводятся постранично и вы всегда хотели сделать так на своем сайте. Сегодня я расскажу как сделать постраничный вывод из MySQL.

Для начала немного теории. Что надо сделать? Сначала, надо проверить выбрана ли страница просмотра. Потом надо подсчитать откуда выводить записи. Делается это просто: текущую страницу умножаем на количество записей на страницу. Наконец, надо сделать SQL-запрос к базе данных и вывести результат. И в конце концов написать нивигацию.

Приступим. Выполните SQL-запрос:

CREATE TABLE tbl_books (book_id int(11) NOT NULL auto_increment, book_name varchar(50) NOT NULL default "", book_cash float NOT NULL default "0", PRIMARY KEY (book_id)) TYPE=MyISAM; INSERT INTO tbl_books VALUES (1, "Книга номер 1", "2"); INSERT INTO tbl_books VALUES (2, "Книга номер 2", "3"); INSERT INTO tbl_books VALUES (3, "Книга номер 3", "4"); INSERT INTO tbl_books VALUES (4, "Книга номер 4", "5"); INSERT INTO tbl_books VALUES (5, "Книга номер 5", "6"); INSERT INTO tbl_books VALUES (6, "Книга номер 6", "7"); INSERT INTO tbl_books VALUES (7, "Книга номер 7", "8"); INSERT INTO tbl_books VALUES (8, "Книга номер 8", "9"); INSERT INTO tbl_books VALUES (9, "Книга номер 9", "10"); INSERT INTO tbl_books VALUES (10, "Книга номер 10", "11"); INSERT INTO tbl_books VALUES (11, "Книга номер 11", "12"); INSERT INTO tbl_books VALUES (12, "Книга номер 12", "13"); INSERT INTO tbl_books VALUES (13, "Книга номер 13", "14"); INSERT INTO tbl_books VALUES (14, "Книга номер 14", "15"); INSERT INTO tbl_books VALUES (15, "Книга номер 15", "16");

Я предлагаю все оформить в виде функций обработчиков. Создадим функцию page(), которая обрабатывает данные о запрошенном номере страницы:

Что она делает? Проверяет выбрана ли страница и если в ней присутствуют буквы, то выводит сообщение об ошибке. Далее сделаем SQL-запрос:

function sql_query($onpage, $page, $table) { $begin = $page*$onpage; // откуда начинать $sql = "SELECT * FROM ".$table." LIMIT ".$begin.", ".$onpage; $result = mysql_query($sql) or die(mysql_error()); return $result; }

Функция навигации:

function navigation($onpage, $page, $table) { $return = null; $count = mysql_query("SELECT COUNT(*) FROM tbl_books") or die(mysql_error()); $count = mysql_fetch_array($count); $count = $count; $pages = $count/$onpage; if($page!==0){ $prev = "<"; } else { $prev = "<"; } if($page

С функциями покончили! Как ими пользоваться?

$onpage = 4; // записей на страницу $table = "tbl_books"; // из какой таблицы mysql_connect("localhost", "root", "pass") or die(mysql_error()); // коннект к БД mysql_select_db("test"); // выбор БД $page = page(); // определяем страницу $result = sql_query($onpage, $page, $table); // sql - запрос while($data = mysql_fetch_array($result)) // цикл вывода { // шаблон вывода нужно изменить // $data["название_поля"] - содержание поля echo $data["book_id"]." ".$data["book_name"]."
"; echo $data["book_cash"]."$

"; } $navigation = navigation($onpage, $page, $table); // определим навигацию echo $navigation; // выведем ее mysql_close(); // отключение от БД?>

Хорошо Плохо

    Что такое разбивка на страницы? Самый простой пример - поисковые машины. Вы даете команду на поиск в ответ на что сервер выдает тысячи ссылок (и прочая информация…