"Постраничный вывод на PHP"
На форуме CodeNet.Ru неоднократно задавали вопрос о том, как сделать постраничный вывод на PHP. Я объяснял, что такое LIMIT, и как его использовать в MySql.
Но все время оказывалось, что вопрос касался только навигации по страницам:
Вот универсальная процедура, выводящая такой блок ссылок:
- $records - всего записей
- $r_start - текущая страница
- $URL - адрес, заканчивающийся на "="
- $inpage - записей на страницу
<?
function LeftRight($records,$r_start,$URL,$inpage) {
$str="";
if ($records<=$inpage) return;
if ($r_start!=0) {
$str.="<a href=".$URL."0><<</a> ";
$str.="<a href=$URL".($r_start-1)."><</a> ";
}
else $str.="<< < ";
if ($r_start==0) {$sstart=$r_start-0;$send=$r_start+10;}
if ($r_start==1) {$sstart=$r_start-1;$send=$r_start+9;}
if ($r_start==2) {$sstart=$r_start-2;$send=$r_start+8;}
if ($r_start==3) {$sstart=$r_start-3;$send=$r_start+7;}
if ($r_start==4) {$sstart=$r_start-4;$send=$r_start+6;}
if ($r_start>=5) {$sstart=$r_start-5;$send=$r_start+5;}
if ($send*$inpage>$records) $send=$records/$inpage;
if ($sstart<0) $sstart=0;
if ($records%$inpage==0) $add=0; else $add=1;
for ($i=$sstart;$i<$send;$i++) {
if ($i==$r_start) $str.=" <B>".($i+1)."/".(intval($records/$inpage)+$add)."</B> | ";
else $str.="<a href=$URL".($i)."><U><B>".($i+1)."</B></U></a> | ";
}
if ($r_start+(1-$add)<intval($records/$inpage)) {
$str.=" <a href=$URL".($r_start+1).">></a>";
$str.=" <a href=$URL".(intval($records/$inpage)-(1-$add)).">>></a>";
}
else $str.=" > >>";
return($str);
}
// Пример вызова
print "<center>".LeftRight(567,43,"index.htm?start=",20)."</center>";
?>
Оставить комментарий
Оставлять комментарии могут только зарегистрированные пользователи.
Если вы не являетесь зарегистрированным пользователем, то вам необходимо зарегистрироваться. Регистрация бесплатна. Если вы уже зарегистрированы на CodeNet, то вам необходимо ввести логин и пароль в верхней (Alt-U) части страницы.
Комментарии
1. Bridun / 04 февраля 2011, 16:46:12

Привет всем помогите сделать постраничный вывод для гостевой 

Это сам вывод с гостевой как его разбить постранично потому что много собирается
у тех примерах я шотоникак немогу разобраться молодой в этом деле
<?php
$message_file = file("engine/quest.csv");
foreach($message_file as $line)
{
$elem = explode(";",$line);
echo("<tr>
<td align=center valign=top colspan=2><b>Имя :</b> $elem[1] ( <b>$elem[2]</b> )</td>
</tr>
<tr>
<td align=center valign=top width=50%><b>E-mail :</b> <a href=mailto:$elem[3] target=_blank>$elem[3]</a></td>
<td align=center valign=top width=50%><b>Сайт :</b> <a href=$elem[4] target=_blank>$elem[4]</a></td>
</tr>
<tr>
<td valign=top colspan=2><div style=margin-left:20px; ><b>Вопрос </b>№ ($elem[0]) $elem[5]</div></td>
</tr>
<tr>
<td align=right valign=top colspan=2><small>Написано : $elem[6]</small></td>
</tr>
<tr>
<td bgcolor=#E0F1F7 valign=top colspan=2 ><div style=margin-left:20px;><b><font color=red>$elem[7]</font></b></div></td>
</tr>
<tr>
<td valign=top colspan=2 > </td>
</tr>");
}
echo("</table>");
?>
2. 2rist / 24 октября 2007, 18:46:46

Спасибо автору за статейку. Поставил, но нашел несколько моментов, где можно было код оптимизировать... и добавить комментариев ;)

[php]
function LeftRight($records,$r_start,$URL,$inpage) {
$str="";
if($records<=$inpage) return;
if($r_start!=0) {
$str.="<a href=".$URL."0>«</a> ";
$str.="<a href=$URL".($r_start-1).">‹</a> ";
}else $str.="« ‹ ";
#Считаем количество страниц
if($records%$inpage==0) $add=0; else $add=1;
$page_count=(intval($records/$inpage)+$add);
#Ссылки на первые 10 страниц, начиная с первой
if($r_start<5) {
$sstart=0;
$send=10;
}
#Ссылки на 10 страниц, влево и вправо по 5, относительно текущей
if($r_start>=5 and $r_start<=($page_count-5)){
$sstart=$r_start-5;
$send=$r_start+5;
}
#Ссылки на последние 10 страниц
if($r_start>($page_count-5)) {
$sstart=$page_count-10;
$send=$page_count;
}
if($sstart<0) $sstart=0;
if($send*$inpage>$records) $send=[highlight]$page_count[/highlight];
#Выводим список ссылок
for($i=$sstart;$i<$send;$i++) {
if($i==$r_start) $str.="<b>".($i+1)."</b> ";
else $str.="<a href=$URL".($i)."><u><b>".($i+1)."</b></u></a> ";
}
if([highlight]$r_start+1<$page_count[/highlight]) {
$str.="<a href=$URL".($r_start+1).">›</a>";
$str.=" <a href=$URL".([highlight]$page_count-1)[/highlight].">»</a>";
}
else $str.="› »";
return($str);
}
[/php]
Перед вызовом, я добавил небольшую проверку, на случай ручного ввода в строку адреса браузера, номера страницы, превышающего "допустимые" значения.
[php]
if($records%$inpage==0) $add=0; else $add=1;
$page_count=(intval($records/$inpage)+$add);
[highlight]if($r_start>$page_count or $r_start<0) $r_start=0;[/highlight]
print "<center>".LeftRight($records,r_start,"index.php?start=",$inpage)."</center>";
[/php]
Вроде все)
3. rbarinov / 16 августа 2007, 15:52:05



Код:
<?
/* Классы поддержки навигации в данных ( navigation_classes.php ) */
/*
* Класс постраничного вывода информации.
* Конструктору передается информация для вывода.
* @author : Barinov Roman
* @version : no
* @date created : 16.08.2007
* @date modifyed : no
*/
class page_navigation_printer {
var $navig_len;
var $url;
/* конструктор класса */
function page_navigation_printer ($in_navig,$selfurl) {
$this->navig_len = $in_navig;
$this->url = $selfurl;
}
/* печатаем единичную ссылку на страницу */
function print_navigation_link ($page_number) {
$a = $page_number+1;
echo "<td><a href='".$this->url."?page=$page_number'>".$a."</a></td>";
}
/* печатаем навигационную полосу */
function make_nagivation_panel () {
echo "<table><tr>";
for ($i=0;$i<$this->navig_len;$i++) {
$this->print_navigation_link($i);
}
echo "</tr></table>";
}
}
/*
* Класс поддержки навигации информации по страницам.
* Конструктору передается информация , он разбивает ее по страницам.
* @author : Barinov Roman
* @version : no
* @date created : 16.08.2007
* @date modifyed : no
*/
class page_navigation_maker {
var $in_array;
var $page_len;
var $page_counter;
var $array_len;
var $current_page_len;
var $current_page_number;
/* Конструктор класса */
function page_navigation_maker ( $data_income, $step ) {
$this->in_array = $data_income;
$this->page_len = $step;
$this->array_len = count($this->in_array);
$this->page_counter = ceil($this->array_len / $this->page_len) ;
}
/* Получаем страницу длиной в $this->data_step , под номером $page_number */
function get_page ( $page_number ) {
$start_position = ($this->page_len * $page_number);
$arr = array();
for ($i=0;$i < $this->page_len;$i++) {
if (isset($this->in_array[$i + $start_position])) $arr[] = $this->in_array[$i + $start_position];
}
$this->current_page_len = count($arr);
$this->current_page_number = $page_number;
return $arr;
}
/* Получаем количество страниц в списке */
function get_pages_count() {
return $this->page_counter;
}
/* Получаем количество Элементов списка */
function get_all_count() {
return $this->array_len;
}
/* Получаем количество элементов текущего листа */
function get_current_length() {
return $this->current_page_len;
}
function get_start_page_index() {
return ($this->current_page_number) * $this->page_len;
}
}
?>
/* Классы поддержки навигации в данных ( navigation_classes.php ) */
/*
* Класс постраничного вывода информации.
* Конструктору передается информация для вывода.
* @author : Barinov Roman
* @version : no
* @date created : 16.08.2007
* @date modifyed : no
*/
class page_navigation_printer {
var $navig_len;
var $url;
/* конструктор класса */
function page_navigation_printer ($in_navig,$selfurl) {
$this->navig_len = $in_navig;
$this->url = $selfurl;
}
/* печатаем единичную ссылку на страницу */
function print_navigation_link ($page_number) {
$a = $page_number+1;
echo "<td><a href='".$this->url."?page=$page_number'>".$a."</a></td>";
}
/* печатаем навигационную полосу */
function make_nagivation_panel () {
echo "<table><tr>";
for ($i=0;$i<$this->navig_len;$i++) {
$this->print_navigation_link($i);
}
echo "</tr></table>";
}
}
/*
* Класс поддержки навигации информации по страницам.
* Конструктору передается информация , он разбивает ее по страницам.
* @author : Barinov Roman
* @version : no
* @date created : 16.08.2007
* @date modifyed : no
*/
class page_navigation_maker {
var $in_array;
var $page_len;
var $page_counter;
var $array_len;
var $current_page_len;
var $current_page_number;
/* Конструктор класса */
function page_navigation_maker ( $data_income, $step ) {
$this->in_array = $data_income;
$this->page_len = $step;
$this->array_len = count($this->in_array);
$this->page_counter = ceil($this->array_len / $this->page_len) ;
}
/* Получаем страницу длиной в $this->data_step , под номером $page_number */
function get_page ( $page_number ) {
$start_position = ($this->page_len * $page_number);
$arr = array();
for ($i=0;$i < $this->page_len;$i++) {
if (isset($this->in_array[$i + $start_position])) $arr[] = $this->in_array[$i + $start_position];
}
$this->current_page_len = count($arr);
$this->current_page_number = $page_number;
return $arr;
}
/* Получаем количество страниц в списке */
function get_pages_count() {
return $this->page_counter;
}
/* Получаем количество Элементов списка */
function get_all_count() {
return $this->array_len;
}
/* Получаем количество элементов текущего листа */
function get_current_length() {
return $this->current_page_len;
}
function get_start_page_index() {
return ($this->current_page_number) * $this->page_len;
}
}
?>
пример вызова :
Код:
<?php
include_once ('./navigation_classes.php');
$a = array(5,6,324,2,4,6,7,8,3,6,34,42,764,132,47,7645,14,65,76,13,54,13,654,3);
echo "обычный вывод: ";
$i = 0;
while ($i < count($a)) {
echo $a[$i]." ";
$i++;
}
echo "<br>";
echo "Постраничный вывод. кол-во страниц : ";
$navig_maker = new page_navigation_maker($a,7);
$page_counter = $navig_maker->get_pages_count();
echo $page_counter;
$navig_panel = new page_navigation_printer($page_counter,$_SERVER['PHP_SELF']);
$navig_panel->make_nagivation_panel();
echo "<br>";
if (isset($_GET['page'])) {
echo "<table border=1><tr><td>Номер строки</td><td>Значение</td></tr>";
$page_array = $navig_maker->get_page($_GET['page']);
$i = 0;
$pp = $navig_maker->get_start_page_index();
while ($i < $navig_maker->get_current_length()) {
$pp++;
echo "<tr><td>".$pp."</td><td>".$page_array[$i]."</td></tr>";
$i++;
}
echo "</table>";
}
$navig_panel->make_nagivation_panel();
?>
include_once ('./navigation_classes.php');
$a = array(5,6,324,2,4,6,7,8,3,6,34,42,764,132,47,7645,14,65,76,13,54,13,654,3);
echo "обычный вывод: ";
$i = 0;
while ($i < count($a)) {
echo $a[$i]." ";
$i++;
}
echo "<br>";
echo "Постраничный вывод. кол-во страниц : ";
$navig_maker = new page_navigation_maker($a,7);
$page_counter = $navig_maker->get_pages_count();
echo $page_counter;
$navig_panel = new page_navigation_printer($page_counter,$_SERVER['PHP_SELF']);
$navig_panel->make_nagivation_panel();
echo "<br>";
if (isset($_GET['page'])) {
echo "<table border=1><tr><td>Номер строки</td><td>Значение</td></tr>";
$page_array = $navig_maker->get_page($_GET['page']);
$i = 0;
$pp = $navig_maker->get_start_page_index();
while ($i < $navig_maker->get_current_length()) {
$pp++;
echo "<tr><td>".$pp."</td><td>".$page_array[$i]."</td></tr>";
$i++;
}
echo "</table>";
}
$navig_panel->make_nagivation_panel();
?>
4. itiro O'kada / 12 июня 2006, 17:00:03

А воттак даже чють быстрее получается и без избыточности и перехлесте условий

Код:
if ($records%$inpage==0) $add=0; else $add=1;
$ggg=(intval($records/$inpage)+$add);
if ($r_start<5) {
$sstart=0;
$send=10;
}
if ($r_start>=5 and $r_start<=($ggg-5)) {
$sstart=$r_start-5;
$send=$r_start+5;
}
if ($r_start>($ggg-5)) {
$sstart=$ggg-10;
$send=$ggg;
}
$ggg=(intval($records/$inpage)+$add);
if ($r_start<5) {
$sstart=0;
$send=10;
}
if ($r_start>=5 and $r_start<=($ggg-5)) {
$sstart=$r_start-5;
$send=$r_start+5;
}
if ($r_start>($ggg-5)) {
$sstart=$ggg-10;
$send=$ggg;
}
5. itiro O'kada / 12 июня 2006, 16:45:54

Исправлена ошибка количества ссылок при переходе на 5 последних "страниц."

Вместо
/*
if ($r_start==0) {$sstart=$r_start-0;$send=$r_start+10;}
if ($r_start==1) {$sstart=$r_start-1;$send=$r_start+9;}
if ($r_start==2) {$sstart=$r_start-2;$send=$r_start+8;}
if ($r_start==3) {$sstart=$r_start-3;$send=$r_start+7;}
if ($r_start==4) {$sstart=$r_start-4;$send=$r_start+6;}
if ($r_start>=5) {$sstart=$r_start-5;$send=$r_start+5;}
*/
пишем следующее
if ($records%$inpage==0) $add=0; else $add=1;
$ggg=(intval($records/$inpage)+$add);
if ($r_start<5) {$sstart=0;$send=10;}
if ($r_start>=5) {$sstart=$r_start-5;$send=$r_start+5;}
if ($r_start>($ggg-5)) {$sstart=$ggg-10;$send=$ggg;}
6. Enemy / 23 мая 2006, 20:04:08

Код конечно хороший но у меня почему-то на второй странице выводит вместо 10 указаных на страницу 20...

может я неправиьлно делаю цикл вывода while($list=mysql_fetch_array($list_result))???
7. D@nil / 11 апреля 2006, 06:57:12

Так правильно юзать:

Код:
$page = $_GET['page'];
$page_posts = 10; // Количество файлов на страницу
$query="SELECT something FROM table LIMIT
$page*$page_posts, ($page*$page_posts+$page_posts)";
-- почикано --
echo LeftRight($count,$page,"?page=",$page_posts);
$page_posts = 10; // Количество файлов на страницу
$query="SELECT something FROM table LIMIT
$page*$page_posts, ($page*$page_posts+$page_posts)";
-- почикано --
echo LeftRight($count,$page,"?page=",$page_posts);
2Fluffy Fear
проше так $str = substr($str, 0, -3);
8. Fluffy Fear / 05 марта 2006, 03:06:47

Заметил в коде как минимум 2 недоделки.

1-я(эстетичская):
После начальных "<< <" отсутствует вертикальная черта, однако перед последними она есть. Может так и задумано, но всё-таки я считаю это неточностью. Для исправления нужно либо
вставить перед циклом (for, который всего один)
Код:
$str.= ' | ';
либо убрать последние символы после цикла,
например так:
Код:
$str = substr($str, 0, strlen($str)-3);
2-я(практическая): Вы, вероятно, заметили(или нет), что когда выбираете страницы из последней десятки, то общее количество ссылок на страницы уменьшается с 10 до 6(коряво написал, но надеюсь понятно). Для исправления придётся добавить код
Код:
if ($r_start==0) {$sstart=$r_start-0;$send=$r_start+10;}
if ($r_start==1) {$sstart=$r_start-1;$send=$r_start+9;}
if ($r_start==2) {$sstart=$r_start-2;$send=$r_start+8;}
if ($r_start==3) {$sstart=$r_start-3;$send=$r_start+7;}
if ($r_start==4) {$sstart=$r_start-4;$send=$r_start+6;}
if ($r_start>=5) {$sstart=$r_start-5;$send=$r_start+5;}
if ($r_start==1) {$sstart=$r_start-1;$send=$r_start+9;}
if ($r_start==2) {$sstart=$r_start-2;$send=$r_start+8;}
if ($r_start==3) {$sstart=$r_start-3;$send=$r_start+7;}
if ($r_start==4) {$sstart=$r_start-4;$send=$r_start+6;}
if ($r_start>=5) {$sstart=$r_start-5;$send=$r_start+5;}
Только ЕГО НУЖНО ПЕРЕДЕЛАТЬ ДЛЯ КОНЦА СТРОЧКИ(мне лень :), я сделал по своему, короче, но не так наглядно).
9. Дмитрий / 06 апреля 2005, 13:52:51

Очень хорошая статья. После того как я ее внедрил у себя в страницах, сильно поубавилось лишнего коду. Главное, что универсально. Правда для новичков желательно было бы слегка пояснить и исправить названия переменных в функции.

Значит, выборка делается так:
$query="SELECT something FROM table LIMIT $start, $inpage";
А в функции переменную $r_start исправить на $start.
Побольше бы таких полезных статей.
10. SLA / 17 февраля 2005, 15:39:22

В ORACLE нет ключевого слова LIMIT. Как "выкрутиться" из этого положения:

SELECT t1.rn, t1.col1 FROM
(
SELECT rownum rn, col1 FROM Table1
) t1
WHERE t1.rn BETWEEN 11 AND 20;
Подробнее написано здесь:
http://www.arrowsent.com/oratip/tip41.htm
но если нужно выбрать много колонок, то проще так:
SELECT * FROM
(
SELECT rownum rn, col1, col2, col3 FROM table
WHERE rownum <= 20
ORDER BY col1
)
WHERE rn >= 11;
Примечание: в последнем варианте сортировку (ORDER BY) нельзя выносить за скобки (т.е. во внешний запрос), иначе сортировка будет неправильной.
11. Moses Fender / 22 октября 2004, 14:52:11

У меня была реализация такой панельки несколько времени назад. Очень похожа:

//nav_bar('адрес ссылки','количество записей','стартовый номер возвращенной записи','количество записей на странице');
function nav_bar($url,$numres,$start=0,$units=20)
{
global $gl; //Единственная глобальная переменная - массив переменных для всех функций сайта. Здесь используется $gl['nav_bar_items'] - количество ссылок в панели.
//Всего юнитов для бара - частное от количества возвращенных записей
//и количества записей на странице.
$num_units_all=ceil($numres/$units);
//Актуальный блок бара. Частное от частного стартового номера возвращенной записи
//и количества записей на странице, и количества юнитов в блоке бара.
$actual_block=floor(($start/$units)/$gl['nav_bar_items']);
//Последний блок юнитов (количество блоков). Частное от количества возвращенных записей
//и количества юнитов в баре
$end_block=$num_units_all/$gl['nav_bar_items'];
//Стартовый номер юнита в актуальном блоке на баре. Произведение номера текущего блока
//с количеством юнитов на баре плюс единица.
$start_unit=floor(($actual_block*$gl['nav_bar_items'])+1);
//Конечный номер юнита в баре. Сумма стартового юнита с количеством юнитов в баре.
$end_unit=$start_unit+$gl['nav_bar_items'];
//Текущий юнит. Частное от суммы стартового номера возвращенной записи с количеством записей
//на странице и количества юнитов в баре
$actual_unit=ceil($start/$units)+1;
$ret="<div style=\"$gl[style] padding-top: 5px; padding-bottom: 10px;\" align=\"center\">";
if($actual_block>0) $ret.='<a href="'.$url.'&f='.(int)((($start_unit-1)*$units)-$units).'" target="_self"><<<предыдущие '.$gl['nav_bar_items'].'</a> ';
//Цикл от стартового до конечного юнитов.
for($n=$start_unit; $n<$end_unit; ++$n)
{
if($n<=$num_units_all)
if($n<>$actual_unit) $ret.='<a href="'.$url.'&f='.(int)(($n*$units)-$units).'" target="_self">['.$n.']</a>';
elseif($n==$actual_unit) $ret.='<span style="font-weight: bold; font-size: 14px">['.$n.']</span>';
// $start=$start+$units;
}
if($actual_block<($end_block-1)) $ret.='<a href="'.$url.'&f='.(int)(($end_unit-1)*$units).'" target="_self"> следующие '.$gl['nav_bar_items'].'>>></a> ';
return $ret.'</div>';
}

