Ограниченный вывод в цикле

153
06 февраля 2020, 13:50

Добрй день. Есть код, который выводит пагинацию на сайте. Но дело в том, что он выводит все ссылки. Например, если у меня 1000 записей в БД, то скрипт выведет 500 ссылок на страницы (если по 2 записи на страницу). Подскажите, пожалуйста, как сделать так, что бы в пагинации отображалось страниц 5, например.

if (isset($_GET['page'])) {
    $CUR_PAGE=($_GET['page']);
} else {
    $CUR_PAGE=1;
}
$res=mysql_query("SELECT count(*) FROM articles");
$row=mysql_fetch_row($res);
$total_rows=$row[0];
$ITEM_PER_PAGE = 2;
$start=abs(($CUR_PAGE-1)*$ITEM_PER_PAGE);
$sql=mysql_query("SELECT * FROM articles ORDER BY id DESC LIMIT $start,$ITEM_PER_PAGE");
require_once 'tpl/index.php';
$uri=strtok($_SERVER['REQUEST_URI'],"?")."?";
if (isset($_GET['page'])) unset($_GET['page']);
if (count($_GET)) {
  foreach ($_GET as $k => $v) {
      if ($k != "page") $uri.=urlencode($k)."=".urlencode($v)."&";
  }
}
$num_pages=ceil($total_rows/$ITEM_PER_PAGE);
for($i=1;$i<=$num_pages;$i++) $PAGES[$i]=$uri.'page='.$i;
if ($CUR_PAGE <=1) {
    echo '<span>Prev</span>';
} else {
    $j = $CUR_PAGE - 1;
    echo '<a href="?page='.$j.'">Prev</a>';
}
foreach ($PAGES as $i => $link) {
    if ($i == $CUR_PAGE) {
        echo '<b>'.$i.'</b>';
    } else {
        echo '<a href="'.$link.'">'.$i.'</a>';
    }
}
if ($CUR_PAGE == $num_pages) {
    echo '<span>Next</span>';
} else {
    $j = $CUR_PAGE + 1;
    echo '<a href="?page='.$j.'">Next</a>';
}
if ($CUR_PAGE == $num_pages) {
    echo '<span>Last</span>';
} else {
    echo '<a href="?page='.$num_pages.'">Last</a>';
}
Answer 1

Задача простая и без использования шаблонизаторов и готовых компонентов ее можно решить следующим образом:

$currentPage = 1; //текущая страница (CUR_PAGE)
$maxPagesCount = 5; //общее количество страниц (num_pages)
$paginatorHtmlContent = ''; //Переменная для хранения HTML кода паджинатора
$minPage = max(1, $currentPage - 5); //Минимальная страница которую нужно вывести - 5 
$maxPage = min($maxPagesCount, $currentPage + 5); //Максимальная страница от текущей + 5
for($i = $minPage;$i <= $maxPage;$i++) {
    if($maxPagesCount >= 1) {
        if($i === $currentPage) {
            $paginatorHtmlContent .= "<b>{$i}</b>";
        } else {
            $paginatorHtmlContent .= "<a href='?page={$i}'>{$i}</a>";
        }
    }
}
echo $paginatorHtmlContent;

Я хочу высказать некоторые рекомендации относительно вашего кода:

  1. Прекратите использовать mysql* расширение, если это новый проект, переходите на более новые библиотеки вида PDO и mysqli;
  2. Откажитесь от конкатенации переменных получаемых от пользователя в запросе к базе данных, т.к. с таким подходом велика вероятность SQL-инъекции;
  3. Именуйте переменные в едином стиле;
  4. Начните разделять данные приложения, пользовательский интерфейса и управляющую логику. Например, можете попробовать какой-нибудь фреймворк.
Answer 2

Ну это же просто! Отвлекитесь на минутку от sql и html. У вас есть 500 штук и надо вывести только 5 штук.

$limit = 5;
for ($i = 0; $i < $limit; ++$i) {
    echo $i . "\n";
}

Неплохо а? Теперь надо вывести 5 штук не с начала а с текущей позиции (половину слева, половину справа от текущей позиции).

$current = 15;
$limit = 5;
$from = $current - floor($limit / 2);
for ($i = 0; $i < $limit; ++$i) {
    echo $from + $i . "\n";
}

Огонёк! Одно только нехорошо -- $from может оказаться < 1 или > 500, а этого бы не хотелось.

$all = 500;
$current = 15;
$limit = 5;
$from = $current - floor($limit / 2);
if ($from < 1) {
    $from = 1;
} elseif ($from > $all - $limit + 1) {
    $from = $all - $limit + 1;
}
for ($i = 0; $i < $limit; ++$i) {
    echo $from + $i . "\n";
}

Но кажется тут закралась ошибка. Что будет если $all < $limit? Надо это поправить.

$all = 4;
$current = 3;
$limit = min($all, 5);
$from = $current - floor($limit / 2);
if ($from < 1) {
    $from = 1;
} elseif ($from > $all - $limit + 1) {
    $from = $all - $limit + 1;
}
for ($i = 0; $i < $limit; ++$i) {
    echo $from + $i . "\n";
}

Ну и не забывайте, что вам не обязательно сразу делать echo, обычно удобно собрать какой-нибудь объект Pagination, который можно потом проитерировать в шаблоне.

READ ALSO
Как реализовать поиск по txt файлу? VK API PHP

Как реализовать поиск по txt файлу? VK API PHP

Суть проблемы/идеи такова

192
php и ajax работают долго

php и ajax работают долго

Есть корзина товаров, работает с помощью сессии, а также php обработчик и js файл, который шлет Ajax запросы в обработчик

128
Какими методами можно вывести и как правильно выводить на страницу данные полученные от сервера в результате обработки Ajax запроса?

Какими методами можно вывести и как правильно выводить на страницу данные полученные от сервера в результате обработки Ajax запроса?

Я постараюсь описать как можно подробнее суть моей проблемы, что я пытаюсь сделать и что я уже пробовал сделать, итак

144
Как справиться с ошибкой [pool www] seems busy?

Как справиться с ошибкой [pool www] seems busy?

Помогите настроить PHP-FPM

152