【问题标题】:Pagination Problem [PHP]分页问题 [PHP]
【发布时间】:2010-09-23 09:50:42
【问题描述】:

所以我在 PHP 中执行此操作,但这是一个逻辑问题,因此我将尝试尽可能通用地编写它。

首先介绍这个分页脚本的工作原理:

  1. for (绘制前三页链接)
  2. if (如果#1 的页面和#3 的页面之间有页面,则绘制省略号 (...))
  3. for(绘制当前页面和它两侧的两个页面链接
  4. if (如果#3 的页面和#5 的页面之间有页面,则绘制省略号 (...))
  5. for (绘制最后三页链接)

问题在于,当页面数量较少时(当页面计数为 10 时,我注意到了这一点)应该有一个省略号,但没有绘制。

进入代码:

$page_count = 10; //in actual code this is set properly
$current_page = 1; //in actual code this is set properly

for ($i = 1;$i <= 3;$i++)
{
    if ($page_count >= $i)
        echo $i;
}

if ($page_count > 3 && $current_page >= 7)
    echo "...";

for ($i = $current_page - 2;$i <= current_page + 2;$i++)
{
    if ($i > 3 && $i < $page_count - 2)
        echo $i;
}

if ($page_count > 13 && $current_page < $page_count - 5)
    echo "...";

for ($i = $page_count - 2;$i <= $page_count;$i++)
{
    if ($page_count > 3)
        echo $i;
}

所以我认为最好的办法是修改两个省略号 if 语句中的一个以包含这样的情况,但是我已经尝试过并且被难住了。

另外请注意,为了便于阅读,我压缩了这段代码,所以请不要给出“那些 for 循环无效,因为它们会为每次迭代重新计算 current_page - 2”之类的提示,因为我知道 :)


对于那些想要查看此逻辑当前如何工作的细分的人,这里是示例输出(已修改),其中包含迭代 $page_count 和 $current_page。 http://rafb.net/p/TNa56h71.html

【问题讨论】:

  • 这不是 PHP 问题!请不要添加 PHP 标签,因为代码示例甚至不是用 PHP 编写的!
  • 您可能希望提供工作示例代码,这样想要自己测试您的逻辑的人就不必用他们自己的语言重新实现您的“伪”代码所以他们可以测试它做任何事情。
  • 好的,我把它改成了 PHP 代码:/

标签: php pagination logic


【解决方案1】:
<?php

/**
 * windowsize must be odd
 *
 * @param int $totalItems 
 * @param int $currentPage 
 * @param int $windowSize 
 * @param int $anchorSize 
 * @param int $itemsPerPage 
 * @return void
 */
function paginate($totalItems, $currentPage=1, $windowSize=3, $anchorSize=3, $itemsPerPage=10) {
    $halfWindowSize = ($windowSize-1)/2;

    $totalPages = ceil($totalItems / $itemsPerPage);
    $elipsesCount = 0;
    for ($page = 1; $page <= $totalPages; $page++) {
        // do we display a link for this page or not?
        if ( $page <= $anchorSize ||  
            $page > $totalPages - $anchorSize ||
            ($page >= $currentPage - $halfWindowSize &&
            $page <= $currentPage + $halfWindowSize) ||
            ($page == $anchorSize + 1 &&
             $page == $currentPage - $halfWindowSize - 1) ||
            ($page == $totalPages - $anchorSize &&  
             $page == $currentPage + $halfWindowSize + 1 ))
        {
            $elipsesCount = 0;
            if ($page == $currentPage)
                echo ">$page< ";
            else
                echo "[$page] ";
        // if not, have we already shown the elipses?
        } elseif ($elipsesCount == 0) {
            echo "... ";
            $elipsesCount+=1; // make sure we only show it once
        }
    }
    echo "\n";
}

//
// Examples and output
//

paginate(1000, 1, 3, 3);
// >1< [2] [3] ... [98] [99] [100] 

paginate(1000, 7, 3, 3);
// [1] [2] [3] ... [6] >7< [8] ... [98] [99] [100] 

paginate(1000, 4, 3, 3);
// [1] [2] [3] >4< [5] ... [98] [99] [100] 

paginate(1000, 32, 3, 3);
// [1] [2] [3] ... [31] >32< [33] ... [98] [99] [100] 

paginate(1000, 42, 7, 2);
// [1] [2] ... [39] [40] [41] >42< [43] [44] [45] ... [99] [100] 

【讨论】:

  • 很好的答案——我现在使用的是一个稍微淡化的版本,因为我不需要它作为一个函数,因为你的一些变量是我的常量。请注意,有一个错误;您需要将第 25 行和第 27 行的“- 1”和“+ 1”分别更改为“- 2”和“+ 2”
【解决方案2】:

这可能是一个过于复杂的解决方案,但它确实有效。

我在这里使用了一个数组,而不仅仅是打印,这让我可以“重做”逻辑。

当“页面左右”恰好与左右肩重合时,会出现部分问题。

function cdotinator ( $current_page, $page_count ) 
{
  $stepsize = 3; 
  $elipse = '...';
  # Simple Case. 
  if ( $page_count <= 2 * $stepsize )
  {
    $out = range( 1, $page_count );
    $out[$current_page - 1 ] = '*' . $current_page . '*';
    return $out;
  }
  #Complex Case
  # 1) Create All Pages
  $out = range( 1, $page_count ); 
  # 2 ) Replace "middle" pages with "." placeholder elements 
  for( $i = $stepsize+1 ; $i <= ( $page_count - $stepsize ) ; $i ++ )
  {
    $out[ $i - 1 ] = '.' ; 
  }
  # 3.1 ) Insert the pages around the current page 
  for( $i =  max(1,( $current_page - floor($stepsize / 2) )) ;
       $i <= min( $page_count,( $current_page + floor( $stepsize/2))); 
       $i ++ )
  {
    $out[ $i - 1] = $i;
  }
  # 3.2 Bold Current Item
  $out[ $current_page - 1 ] = '*' . $current_page . '*' ; 

  # 4 ) Grep out repeated '.' sequences and replace them with elipses 
  $out2 = array(); 
  foreach( $out as $i => $v )
  {
    #  end, current  == peek() 
    end($out2);
    if( current($out2) == $elipse and $v == '.' )
    {
        continue;
    }
    if( $v == '.' )
    {
      $out2[] = $elipse; 
      continue;
    }
    $out2[]= $v;
  }

  return $out2;

}

输出可见:http://dpaste.com/92648/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多