Очень часто встречающаяся задача вывести данные из БД, при этом разбив по страницам. Первая идея которая приходит в голову сделать дубль запроса с подсчетом строк и поделить на количество строк которые будут выводиться на одной страницы. Но естественно меня это не устраивает по причинам:

  1. Лишний запрос к БД.
  2. Не удобно использовать, так как функцией сделать для разных видов запросов не возможно, а я хотел, чтобы все считалось именно функцией.

Решением этой задачи стала опция в select запросе - SQL_CALC_FOUND_ROWS которая запоминает количество найденных строк в запросе и возвращает при запросе SELECT FOUND_ROWS(). Эта опция и дает возможность создать функцию которая запускается после основного запроса и выводит список страниц.

Привожу пример функции:

function num_page($page,$num='',$get='yes')
{
	global $rows_page;
	$num=(empty($num)) ? $rows_page : $num;
	$num_rows=mysql_result(mysql_query("SELECT FOUND_ROWS()"), 0);
	$num_page=ceil($num_rows/$num);
	if(!isset($page) or empty($page) or $page>$num_page){$page=1;}
	$str=array();
	$get_q='';
	if($get=='yes')
	{
		foreach($_GET as $k => $v)
		{
			if($k!='page')
			{
				if(is_array($v))
				{
					foreach($v as $val)
					{
						$get_q.=$k.'[]='.urlencode($val).'&';
					}
				}else{
					$get_q.=$k.'='.urlencode($v).'&';
				}
			}
		}
	}
	for($i=1;$i<=$num_page;$i++)
	{
		$str[]=($i!=$page) ? "<a href=\"?".$get_q."page=".$i."\">".$i."</a>" : "<b>".$i."</b>";
	}
	return $str;
}

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

$rows_page=25; // количество строк из БД на странице
if(!isset($_GET['page']) or !(int)$_GET['page']){$_GET['page']=1;}
$query=mysql_query("select SQL_CALC_FOUND_ROWS * from table limit ".(($_GET['page']-1)*$rows_page).", ".$rows_page);
$count_page=num_page($_GET['page']);
echo "<br>Страницы: ".implode(', ',$count_page);