分页使用MySQL LIMIT,OFFSET

时间:2013-12-04 00:12:25

标签: php mysql limit offset

我有一些代码限制数据每页只显示4个项目。我正在使用的列有大约20-30个项目,所以我需要将它们分散在各个页面上。

在第一页上,我有:

    $result = mysqli_query($con,"SELECT * FROM menuitem LIMIT 4");
{
  echo "<tr>";
  echo "<td align='center'><img src=\"" . $row['picturepath'] . "\" /></td>";
  echo "<td align='center'>" . $row['name'] . "</td> <td align='center'> <input type='button' value='More Info'; onclick=\"window.location='more_info.php?';\"> </td>";
  echo "<td align='center'>" . $row['price'] . "</td> <td align='center'> <input type='button' value='Add to Order' onclick=''> </td>";
  echo "</tr>";
 }
echo "</table>";

mysqli_close($con);

    ?> 

    <table width="1024" align="center" >
        <tr height="50"></tr>
            <tr>
                <td width="80%" align="right">
                    <a href="itempage2.php">NEXT</a>
                </td>
                <td width="20%" align="right">
                    <a href="">MAIN MENU</a>
                </td>
            </tr>
    </table>

你会注意到页面底部我的锚标签列出第二页“itempage2.php”。在第2页的项目中,我有相同的代码,但我的select语句列出了4的偏移量。

$result = mysqli_query($con,"SELECT * FROM menuitem LIMIT 4 offset 4");

当我的数据库中有预定数量的项目时,这是可行的。但它并不那么好。我需要创建一个新页面,只有当有更多的项目,而不是像现在这样硬编码。

如何创建多个页面而无需对每个新页面进行硬编码和偏移?

4 个答案:

答案 0 :(得分:78)

首先,每个页面都没有单独的服务器脚本,这只是疯狂。大多数应用程序通过在URL中使用分页参数来实现分页。类似的东西:

http://yoursite.com/itempage.php?page=2

您可以通过$_GET['page']访问所请求的页码。

这使您的SQL配方变得非常简单:

// determine page number from $_GET
$page = 1;
if(!empty($_GET['page'])) {
    $page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT);
    if(false === $page) {
        $page = 1;
    }
}

// set the number of items to display per page
$items_per_page = 4;

// build query
$offset = ($page - 1) * $items_per_page;
$sql = "SELECT * FROM menuitem LIMIT " . $offset . "," . $items_per_page;

例如,如果此处的输入为page=2,每页有4行,则您的查询将为“

SELECT * FROM menuitem LIMIT 4,4

这就是分页的基本问题。现在,您还需要了解总页数(以便您可以确定是否应显示“下一页”,或者是否允许通过链接直接访问页面X。)

为此,您必须了解表格中的行数。

您可以在尝试返回实际的有限记录集之前使用数据库调用执行此操作(我之前说过,因为您显然希望验证所请求的页面是否存在)。

这实际上非常简单:

$sql = "SELECT your_primary_key_field FROM menuitem";
$result = mysqli_query($con, $sql);
if(false === $result) {
   throw new Exception('Query failed with: ' . mysqli_error());
} else {
   $row_count = mysqli_num_rows($result);
   // free the result set as you don't need it anymore
   mysqli_free_result($result);
}

$page_count = 0;
if (0 === $row_count) {  
    // maybe show some error since there is nothing in your table
} else {
   // determine page_count
   $page_count = (int)ceil($row_count / $items_per_page);
   // double check that request page is in range
   if($page > $page_count) {
        // error to user, maybe set page to 1
        $page = 1;
   }
}

// make your LIMIT query here as shown above


// later when outputting page, you can simply work with $page and $page_count to output links
// for example
for ($i = 1; $i <= $page_count; $i++) {
   if ($i === $page) { // this is current page
       echo 'Page ' . $i . '<br>';
   } else { // show link to other page   
       echo '<a href="/menuitem.php?page=' . $i . '">Page ' . $i . '</a><br>';
   }
}

答案 1 :(得分:4)

使用.. LIMIT :pageSize OFFSET :pageStart

:pageStart绑定到the_page_index(即第一页为0)* number_of_items_per_pages(例如4)和:pageSize绑定到number_of_items_per_pages。

要检测“有更多页面”,请使用SQL_CALC_FOUND_ROWS或使用.. LIMIT :pageSize OFFSET :pageStart + 1并检测丢失的最后一页(pageSize + 1)。不用说,对于索引> gt的页面; 0,存在上一页。

如果页面索引值嵌入在URL中(例如在“上一页”和“下一页”链接中),则可以通过相应的$_GET项获取它。

答案 2 :(得分:3)

如果你想保持简单,请继续尝试。

$page_number = mysqli_escape_string($con, $_GET['page']);
$count_per_page = 20;
$next_offset = $page_number * $count_per_page;
$cat =mysqli_query($con, "SELECT * FROM categories LIMIT $count_per_page OFFSET $next_offset");
while ($row = mysqli_fetch_array($cat))
        $count = $row[0];

剩下的由你决定。 如果你有来自两个表的结果我建议你尝试不同的方法。

答案 3 :(得分:0)

使用OFFSET时,打十二个页面并不重要。但是,当您拥有数百个页面时,您会发现OFFSET对性能不利。这是因为每次都需要读取所有跳过的行。

最好remember where you left off