【问题标题】:Methods to achieve first, previous, next and last navigation实现first、previous、next和last导航的方法
【发布时间】:2010-03-08 17:27:40
【问题描述】:

我是编程新手,对导航有疑问。 如文章或漫画网站中所见,可以实现“第一个”、“上一个”、“下一个”和“最后一个”导航的各种方法是什么? (诚​​然,“第一个”链接并不令人困惑,因为它可以保持静态,但其他链接呢?) 例如,在第 50 页,链接将适当地指向第 49 和 51 页(如果存在,如果不存在,它将不起作用,但会在这样的页面存在时自动变为活动状态。 在大多数示例中,我看到 url 以“.php?id=50”之类的结尾,但不确定它是如何通过数据库实现的? 任何帮助将不胜感激,谢谢。

【问题讨论】:

    标签: php database dynamic navigation pagination


    【解决方案1】:

    URL 末尾的位称为GET 变量。当用户转到一个末尾有一个的页面时,例如:

    example.org/comics/myawesomecomic.php?page=50
    

    服务器转到该页面,并且(通常)服务器端脚本会在将页面输出给用户之前做一些工作。对于 PHP,GET 变量是一个全局变量(与其他变量一样,大变量是 POST 和 COOKIE),php 脚本可以通过获取从服务器传递到脚本的值来检索它,在本例中为 $_GET['page']

    因此,假设您有一个脚本可以处理对漫画故事情节“My Awesome Comic”的所有请求,并且它分为 60 页,那么用户访问任何页面所需要做的就是将 GET 变量更改为页码.您的脚本可能会做一些非常简单的事情,例如获取名为myawesomecomic/ 的目录的内容并获取名为50.html 的文件,然后将其输出给用户。但很有可能,因为你遇到了这个麻烦,你想要一些更复杂的东西,所以它会从数据库中抓取第 50 页并更新所有导航,甚至可能会在右上角抛出一个时尚的50 - 60

    现在,这是最简单的部分,也就是您问题的答案。既然您知道了 GET 变量的工作原理以及服务器脚本对它们的作用,那么您要做的就是按照您的描述进行导航:

    $current_page = $_GET['page'];
    $next_page = $current_page + 1;
    $prev_page = $current_page - 1;
    $first_page = 1;
    $last_page = 
    

    最后一部分将由您自己知道。您可以始终拥有相同数量的页面,或者您可以在拉出当前页面的同时查询数据库,等等。假设您在获取当前页面时确实查询了数据库的总页数。它返回了 60(我们假设,为了避免令人头疼的是 60 是从 1 开始的页数,而不是 0),所以回到导航...

    $last_page = 60;
    

    现在您有了第一个、最后一个、上一个和下一个。假设你熟悉 HTML,剩下的(除了让这个看起来漂亮)是:

     echo "
     <a href='myawesomecomic.php?page=$first_page'>First Page</a>
     <a href='myawesomecomic.php?page=$prev_page'>Previous Page</a>
     <a href='myawesomecomic.php?page=$next_page'>Next Page</a>
     <a href='myawesomecomic.php?page=$last_page'>Last Page</a>
     ";
    

    还有你的导航。显然,您需要安排它们以适合您的网站,而不是让它们像那样一起运行,使用很酷的箭头等。但即使您不做任何花哨的事情,这些链接也可以工作。

    但是!

    我刚刚给了你一个非常棒的“我第一次玩 PHP”的版本。我遗漏的东西(你应该多问问或做一些认真的研究):

    • 由于 GET 变量包含在 URL 中,因此不难弄清楚。我可以轻松地将?page=50 更改为?page=1=1,并且根据您获取内容的方式,我可能只是询问了您数据库的所有内容。 从不将用户输入(甚至是 URL)直接抓取到您的变量中。如果你知道它是页码,那么你就知道它是一个数字。在通过脚本和数据库运行之前检查输入以确保它是一个数字。

    • 如果用户输入的数字超出范围,您需要有一个系统。诸如“抱歉,找不到页面”甚至“找不到页面,从头开始”之类的简单内容并将它们发送回第 1 页,无论如何。如果你什么都不输出,它看起来很糟糕,并且你揭示了可以被操纵的部分脚本逻辑。

    • 当您对 GET 变量感到满意时,我建议您放弃它们以使用 mod_rewrite(假设您在 apache 服务器上)。现在不要跳入,但是当你掌握了窍门后,你可以开始制作如下 URL:example.org/comics/myawesomecomic/page50example.org/comics/myawesomecomic/page/50 或者你有什么。真正发生的是该目录中的所有页面都被重定向到同一个脚本,然后该脚本检查 URL 的结尾以确定从数据库中提取的内容。但对于最终用户来说,它看起来只是一个网页。这看起来更干净(我认为),并且在覆盖脚本逻辑方面做得更多。但我想说的是等待它,因为它还会让您面临其他更难以预料的风险,除非您习惯于清理用户输入并处理标准页面错误,例如“找不到页面”。

    无论如何,弄清楚诸如在当前日期添加一周和向当前页面添加页码之类的东西完全是我进入 PHP 和 Web 应用程序开发的方式,所以我希望这对我有帮助且简单明了。

    【讨论】:

    • 这是一个非常好的答案,会为以后的提问者添加书签,但是如果我在记录 31 中并且记录 30 被删除了怎么办?你必须为此做一些检查,我至少会提到这一点。
    【解决方案2】:

    这种导航称为分页。影响给定页面分页的三个变量:

    • 项目总数
    • 每页的项目数
    • 当前页面

    您通常可以使用如下查询轻松地从数据库中获取项目总数:

    $query = "SELECT COUNT(*) FROM tbl";
    $count = mysql_result($query, 0);
    

    而且你知道每页和当前页的项目数,你就可以算出总共有多少页:

    $perpage = 10; // This you can define yourself
    
    $pages_count  = ceil($count / $perpage);
    

    之后,很容易做一些简单的 if 子句,看看应该显示什么样的导航:

    // Get the current page or set default if not given
    $page = isset($_GET['page']) ? $_GET['page'] : 1;
    
    $pages_count = ceil($count / $perpage);
    
    $is_first = $page == 1;
    $is_last  = $page == $pages_count;
    
    // Prev cannot be less than one
    $prev = max(1, $page - 1);
    // Next cannot be larger than $pages_count
    $next = min($pages_count , $page + 1);
    
    // If we are on page 2 or higher
    if(!$is_first) {
        echo '<a href="index.php?page=1">First</a>';
        echo '<a href="index.php?page='.$prev.'">Previous</a>';
    }
    
    echo '<span>Page '.$page.' / '.$pages_count.'</span>';
    
    // If we are not at the last page
    if(!$is_last) {
        echo '<a href="index.php?page='.$next.'">Next</a>';
        echo '<a href="index.php?page='.$pages_count.'">Last</a>';
    }
    

    要从给定页面的数据库中选择正确的结果,您可以使用如下查询:

    $query = "SELECT * FROM tbl LIMIT ".(int)($page - 1)." ".(int)$perpage;
    

    这就是它的全部内容。希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      也许 this tutorialthis one 会帮助你。

      编辑:嗯,第一个是一个非常烦人的网站。找到了另一个。 :)

      【讨论】:

        【解决方案4】:

        我假设您不是在谈论分页(即将大的记录列表分成多个页面),而是关于记录的详细视图,并预先提供“下一个”/“上一个”链接到下一个和上一个 记录。

        如果您没有找到前一个和最后一个邻居的固定方法(所以您不能只说“当前 ID -1”和“+1”),您将不得不按照您的条件进行数据库查询,并找出上一个和下一个成员。

        也许是深入​​研究问题,而不是您需要开始什么,但我最近问了一个问题,该问题涉及优化问题以及以快速有效的方式执行此“邻居查找”的不同方法。 Caching the results of a “next” / “previous element” query

        【讨论】:

          【解决方案5】:

          有很多方法可以做到这一点,从复杂到简单。 (在google上搜索php分页)。

          某些网址中的 ?id=50 用于确定要从哪个项目开始。

          例如在 sql 中,您使用 SELECT * FROM tbl LIMIT 0,10 确定要选择的项目范围,这将选择记录 0-10。那么SELECT * FROM tbl LIMIT 11,10 会选择 11 到 20。

          【讨论】:

          • 其实LIMIT 11, 20会选择记录11-30,因为LIMIT中的第二个参数是持续时间,而不是终点。
          猜你喜欢
          • 2021-10-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-21
          • 1970-01-01
          • 2010-11-21
          • 1970-01-01
          • 2019-08-12
          相关资源
          最近更新 更多