Существует множество страниц,
$pages = array( 1, 2, 3, ... 100, 101 );
И есть переменная $current_page
. Все, что я пытаюсь сделать, это разбиение на страницы в стиле digg, так что это будет выглядеть так,
< 4 5 6 7 .... 15 16 17 18 >
Первое, что приходит на ум, – получить последние и предыдущие значения массива из определенной позиции, равные $current_page
.
Поэтому я начал с базового цикла, но проблема в том, что количество страниц может быть очень большим, поэтому я не думаю, что это эффективная вещь. Есть ли другой правильный способ сделать это? (возможно, через собственные функции array_*
)?
Следующая функция создает StackOverflow, такую как разбиение на страницы. Цели:
Хотя следующая функция отображает полный пейджер, нас в первую очередь интересует, как рассчитать окружающие страницы a и b как функцию текущей страницы , размера пейджера и количества страниц .
function so_like_pager($current_page, $page_count, $pager_size = 4) { if ($current_page <= $pager_size) { // the pager for first 4 pages starts from 1 $a = 1; $b = min(1 + $pager_size, $page_count); } else { // the pager for remaining pages ends at current page + 2 // and starts so that 4 links are shown $b = min($current_page + ($pager_size >> 1), $page_count); $a = $b - $pager_size; } // return array("show_from" => $a, "show_upto" => $b); echo '<p>'; if ($current_page !== 1) { echo '<a href="' . so_like_pager_page(1) . '">' . 1 . '</a> '; } else { echo '<b>' . 1 . '</b> '; } if ($a > 1 + 1) { echo '<span>...</span> '; } for ($i = $a; $i <= $b; $i++) { if ($i !== 1 && $i !== $page_count) { if ($current_page !== $i) { echo '<a href="' . so_like_pager_page($i) . '">' . $i . '</a> '; } else { echo '<b>' . $i . '</b> '; } } } if ($b < $page_count - 1) { echo '<span>...</span> '; } if ($current_page !== $page_count) { echo '<a href="' . so_like_pager_page($page_count) . '">' . $page_count . '</a> '; } else { echo '<b>' . $page_count . '</b> '; } echo '</p>'; } function so_like_pager_page($page) { return 'page-' . $page . '/'; }
тесты:
so_like_pager(1, 100); so_like_pager(2, 100); so_like_pager(3, 100); so_like_pager(4, 100); so_like_pager(5, 100); so_like_pager(6, 100); so_like_pager(50, 100); so_like_pager(99, 100); so_like_pager(100, 100);
Вывод:
PS: Примечание. Я портировал эту функцию из ASP classic на PHP в спешке и не тестировал ошибки.
function get_surrounding_pages(array $pages, $current, $amount = 2) { $pages_idx = array_flip($pages); if (!isset($pages_idx[$current])) { return false; } $offset = max(0, $pages_idx[$current] - $amount); $limit = $amount + 1 + ($pages_idx[$current] - $offset); return array_slice($pages, $offset, $limit); } $pages = range(1, 1000); $current = 42; get_surrounding_pages($pages, $current, 4); // array(38, 39, 40, 41, 42, 43, 44, 45, 46) // this will work even if your number of pages is not continuous (eg: 1, 2, 6). $pages = array(1, 2, 5, 6, 42, 234, 1048); $current = 6; get_surrounding_pages($pages, $current, 2); // array(2, 5, 6, 42, 234) // also works if you reach the boundaries $pages = range(1, 10); $current = 2; get_surrounding_pages($pages, $current, 2); // array(1, 2, 3, 4) $current = 9; get_surrounding_pages($pages, $current, 2); // array(7, 8, 9, 10) // returns false if you ask a page that doesn't exists $pages = range(1, 10); $current = 42; get_surrounding_pages($pages, $current, 2); // false
Вы можете использовать функцию end
PHP для получения последней записи массива.
<?php $a = array( 1, 2, 3, 4, 5, 10 ); echo end($a);
Вы также можете использовать array_slice
или array_splice
для вырезания массива или array_pop
, который удаляет последний элемент и возвращает то, что было удалено.
Может быть, вы можете попытаться закончить . Должна быть более эффективной, чем цикл.