<?php /** * Постраничная навигация с ООП * автор: Nc_SOft * 08.01.09 */ //класс навигатор представлен ниже, его лучше сохранить в отдельном файле //пример использования: 1.навигация в массиве //это массив 1,2,3,..,100 $arr=range(1,100); //создаем навигатор $n=new Navigator('',5); //всего элементов $all=count($arr); //теперь возьмем 5 элементов из массива при помощи SPL $larr=new LimitIterator(new ArrayIterator($arr), $n->start(), $n->pnumber); //выводим элементы echo '<div>'; foreach ($larr as $k=>$v) { if ($k) echo '<br />'; echo $v; } echo '</div>'; //и печатаем навигацию echo $n->navi($all); //теперь пример с БД //создаем навигатор $n=new Navigator('',5); //делаем запрос(например, к таблице юзеров id|login) $q=mysql_query("SELECT SQL_CALC_FOUND_ROWS id,login FROM users ORDER BY id LIMIT {$n->start()}, $n->pnumber "); $all=mysql_result(mysql_query("SELECT FOUND_ROWS()"),0,0); while (false!==($res=mysql_fetch_assoc($q))) { print_r($res); } //навигация echo $n->navi($all); //а вот и сам навигатор, если есть идеи как его улучшить пишите class Navigator { /** * конструктор * */ function __construct($script,$pnumber,$query='') { $this->script=$script; //если не задано имя скрипта, то используем текущее if (empty($script)) { $this->script=$_SERVER['SCRIPT_NAME']; } //элементов на страницу $this->pnumber=$pnumber; $this->query=''; $this->or_query=$query; //если задана строка параметров if (is_array($query)) { foreach ($query as $k=>$v) { $this->query.='&'.$k.'='.urlencode($v); } } //обработка текущего номера страницы $this->page=isset($_GET['page']) ? (int)$_GET['page'] : 1; } /** * Инициализация навигатора, вычесление стартовой позиции */ function start() { //вычисление стартовой позиции $this->start = $this->page * $this->pnumber - $this->pnumber; //обработка левых номеров if ($this->page < 1) { $this->page=1; $this->start=0; } return $this->start; } /** * Печать навигатора */ function navi($all,$input=0) { //всего элементов $this->all=$all; //число страниц $this->num_pages=ceil($this->all/$this->pnumber); //если страниц более 5, то выводим форму if ($this->num_pages > 5) $input=1; //проверка корректности if ($this->page > $this->num_pages || $this->page < 1) { $this->page=1; $this->start=0; } //не печатаем навигатор, если всего одна страница if ($this->num_pages<2) return ''; $buff='<div class="navi">'; //блок вперед if ($this->page>1) $buff.='<a href="'.$this->script.'?page='.($this->page-1).$this->query.'"><</a>'; else $buff.='<'; //блок ссылок for($pr = '', $i =1; $i <= $this->num_pages; $i++) { $buff.= $pr=(($i == 1 || $i == $this->num_pages || abs($i-$this->page) < 2) ? ($i == $this->page ? " [$i] " : ' <a href="'.$this->script.'?page='.$i.$this->query.'">'.$i.'</a> ') : (($pr == ' ... ' || $pr == '')? '' : ' ... ')); } //блок назад if ($this->page<$this->num_pages) $buff.='<a href="'.$this->script.'?page='.($this->page+1).$this->query.'">></a>'; else $buff.='>'; //печатаем форму с полем ввода (можно это убрать отсюда если не требуется) if ($input) { $buff.='<form style="margin:0" action="'.$this->script.'" method="get"><p style="margin:0">'; $buff.='<input size="2" name="page" value="'.$this->page.'"/>'; if (!empty($this->query)) { foreach ($this->or_query as $name=>$value) { $buff.='<input type="hidden" name="'.$name.'" value="'.htmlspecialchars($value).'" />'; } } $buff.='<input type="submit" value=">>"/></p></form>'; } $buff.='</div>'; return $buff; } }