介绍
分页 是构建数据驱动应用程序中的一个重要概念。当从数据库中提取记录时,可能会获取大量的记录。例如,当运行针对活跃用户或属于特定位置的用户的查询时,可能会返回成百上千的大量用户。在单个网页上显示如此庞大数量的记录并不是一个用户友好的解决方案,因为这会让用户感到不知所措,同时也会破坏用户体验的流畅性。
因此,一个更优的选择是限制记录的数量。这就是分页的概念。换句话说,我们将记录数分成若干页,然后显示该页面。单个页面可以有十个、十五个或任何其他可在前端显示的可行记录数量。
虽然分页可以改善应用程序的整体用户体验,但它也可以使应用程序运行得更快,因为我们可以检索更少数量的记录。因此,客户端和服务器之间在网络上传输的数据更少,从而减少了延迟时间。
在本教程中,我们将构建一个PHP代码来连接数据库,并使用MySQL数据库及其LIMIT子句来实现分页.
前提条件
要学习本教程,您需要:
-
最新版本且正在运行的 Ubuntu。如果需要帮助,请参考如何设置您的 Ubuntu 服务器教程。
-
您还需要安装 PHP 和 MySQL。要设置 PHP 和 MySQL,我们有一个教程:LAMP Stack 设置 – Linux Apache MySQL PHP.
第 1 步 — 设置数据库用户和测试数据库
在本教程中,我们将与 MySQL 数据库建立数据库连接并获取记录。这些记录将使用 table 元素显示在 HTML 页面上。为了建立连接并显示记录,我们将使用 PHP 脚本。一旦我们准备好数据库连接,我们将测试有分页和无分页的应用程序。通过这种方式进行测试将使我们能够理解分页在实际中是如何工作的。
要连接到 MySQL 数据库,我们需要一个示例 MySQL 数据库以及连接到 MySQL 数据库的用户身份验证信息。在这一步中,您将为您的 MySQL 数据库创建一个非 root 用户、一个示例数据库以及一个用于测试 PHP 脚本的表。
首先,登录到您的服务器。然后,使用以下命令登录到 MySQL 服务器:
|
1 |
mysql> sudo mysql -u root -p |
系统将提示您输入 root 用户的密码。输入密码并按 Enter 键继续。接下来,创建一个名为 test_db 的示例数据库,我们将在本教程中使用它。要创建新数据库,请运行以下命令:
|
1 |
mysql> Create database test_db; |
您将看到来自 MySQL 服务器的输出,显示有一行受到影响。接下来,我们需要为此数据库创建一个新用户。我们将授予该用户所有权限。但是,在处理实际应用程序时,请确保限制权限。我们将我们的用户命名为 test_user。在以下命令中,将 PASSWORD 替换为强密码:
|
1 |
mysql> GRANT ALL PRIVILEGES ON test_db.* TO 'test_user'@'localhost' IDENTIFIED BY 'PASSWORD'; |
创建用户后,刷新权限:
|
1 |
mysql> FLUSH PRIVILEGES; |
现在 test_user 和 test_db 都已准备就绪,使用 test_db 来创建表。要切换到 test_db,请运行以下命令:
|
1 |
mysql> Use test_db; |
一旦我们在输出中看到数据库已更改,我们就可以开始创建表了。我们将创建一个名为 Products 的新表来存放产品。对于我们的目的,在此表中我们只需要两列: product_id 和 product_name。我们将设置 product_id 为 AUTO_INCREMENT,这样每次我们添加新产品时它都会递增。另一个名为 product_name 的列将用于存储产品的名称。 product_name 列将用于通过名称区分每个产品:
|
1 |
mysql> Create table products (product_id BIGINT PRIMARY KEY AUTO_INCREMENT, product_name VARCHAR(50) NOT NULL ) Engine = InnoDB; |
现在我们将添加一些 产品 到这个新创建的表中。为此,请运行以下命令:
|
1 2 3 4 5 6 7 8 9 10 |
mysql> Insert into products(product_name) values ('WIRELESS MOUSE'); mysql> Insert into products(product_name) values ('BLUETOOTH SPEAKER'); mysql> Insert into products(product_name) values ('GAMING KEYBOARD'); mysql> Insert into products(product_name) values ('320GB FAST SSD'); mysql> Insert into products(product_name) values ('17 INCHES TFT'); mysql> Insert into products(product_name) values ('SPECIAL HEADPHONES'); mysql> Insert into products(product_name) values ('HD GRAPHIC CARD'); mysql> Insert into products(product_name) values ('80MM THERMAL PRINTER'); mysql> Insert into products(product_name) values ('HDMI TO VGA CONVERTER'); mysql> Insert into products(product_name) values ('FINGERPRINT SCANNER'); |
要验证这些产品是否已输入到表中,请运行以下命令:
|
1 |
mysql> select * from products; |
如果您看到上面输入的产品,说明您已准备好继续。使用以下命令退出 MySQL 数据库:
|
1 |
mysql> quit; |
现在我们已经设置了 MySQL 数据库并输入了测试数据,我们准备好编写 PHP 脚本来连接到该数据库并获取记录。
步骤 2 – 无分页获取和显示记录
如上所述,我们将首先在不进行分页的情况下显示记录。我们将构建一个 PHP 脚本,该脚本连接到 MySQL 数据库并获取记录。我们将连接到上面创建的 test_db,使用 test_user 并获取记录。
我们的 products 表目前只有十条记录。对于许多用户来说,是否需要分页可能并不明显。然而,在不进行分页的情况下测试应用程序将详细说明它如何有助于提升应用程序的整体体验。我们还将了解拆分数据如何有助于创造更好的用户体验并减轻服务器的负担。
在您的 PHP 服务器上,在网站文件夹的文档根目录下,运行以下命令:
sudo nano /var/www/html/pagination_test.php
现在在此文件中,添加以下内容。请确保将 PASSWORD 替换为您的 test_user 的密码值:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php try { $pdo = new PDO("mysql:host=localhost;dbname=test_db", "test_user", "PASSWORD"); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); $sql = "select * from products"; $stmt = $pdo->prepare($sql); $stmt -> execute(); echo "<table border='1' align='center'>"; while (($row = $stmt -> fetch(PDO::FETCH_ASSOC)) !== false) { echo "<tr>"; echo "<td>".$row['product_id']."</td>"; echo "<td>".$row['product_name']."</td>"; echo "</tr>"; } echo "</table>"; } catch(PDOException $e) { echo $e->getMessage(); } ?> |
保存文件。在继续之前,我们将总结一下我们上面所做的工作:
-
首先,我们连接到 MySQL 数据库,为此我们使用了 PHP 数据对象 (PDO) 库。我们使用了上面用于连接 MySQL 数据库的 MySQL 用户的凭据。PDO 是一个非常有用的库,用于连接数据库。它使数据访问层易于编写代码,并允许连接到不同的数据库,而无需对应用程序进行大量的重构。PDO 使用预处理语句,这确保了安全性不会受到损害。因此,查询得以安全地执行。
-
接下来,我们使用了 PDO API 来执行 select * from products 语句。 $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false) 确保 PHP 中的数据类型与数据库中的相同。因此, product_id 和 product_name 分别显示为整数和字符串。
-
The $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 告诉 PDO 在发生错误时抛出异常。通过这样做,我们可以轻松地在 try … catch 块中捕获异常并根据需要进行处理。
现在我们的脚本已经准备好了,我们需要运行它。为此,打开浏览器并访问以下 URL: /var/www/html/pagination_test.php。请确保在 URL 中附加您的服务器 IP。如果您在本地运行,您的 URL 将变为 http://localhost/var/www/html/pagination_test.php.
您将看到以下输出:

在这里,我们的产品被返回并显示在页面上。现在,想象一下如果我们有数百个产品。这将导致一个很长的循环来获取数据并将其显示在页面上。这将增加页面加载时间。
在下一节中,我们将修改 PHP 脚本并包含 MySQL LIMIT 子句。这将解决显示大量记录的问题。我们将添加分页链接,以便用户可以在页面之间进行导航。
步骤 3 – 使用 PHP 设置分页
在此步骤中,我们将使用 PHP 设置分页,以使用多个表格显示数据。为了适应分页,我们将修改在上一步中编写的脚本。
我们将使用 LIMIT MySQL 数据库的子句。在将其添加到脚本之前,让我们看一个 MySQL LIMIT 语法的示例:
|
1 |
mysql> Select [column1, column2, column n...] from [table name] LIMIT offset, records; |
在上述语句中,我们可以看到 LIMIT 子句具有 offset 和 records 参数。 offset 告诉要跳过多少条记录,而 records 告诉每页显示或从数据库中获取的最大记录数。
现在我们知道了分页的工作原理,让我们来看看我们将如何实现它。我们将在每页显示三条记录。因此,如果我们的数据库中有十条记录,我们将通过将总记录数除以每页的记录数来得到四页。由于结果可能不是整数,我们将使用 PHP Ceil 函数向上取整到最接近的整数以获得整数结果。下面是一个简单的代码片段,用于演示 Ceil 函数:
|
1 |
$total_pages=ceil($total_records/$per_page); |
现在我们将添加分页的代码。要启用分页并添加导航链接,请使用以下命令打开 /var/www/html/pagination_test.php 文件:
|
1 |
$ sudo nano /var/www/html/pagination_test.php |
接下来,用以下代码替换此文件的内容:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
<?php try { $pdo = new PDO("mysql:host=localhost;dbname=test_db", "test_user", "PASSWORD"); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); /* 开始分页信息 */ $page = 1; if (isset($_GET['page'])) { $page = filter_var($_GET['page'], FILTER_SANITIZE_NUMBER_INT); } $per_page = 3; $sqlcount = "select count(*) as total_records from products"; $stmt = $pdo->prepare($sqlcount); $stmt->execute(); $row = $stmt->fetch(); $total_records = $row['total_records']; $total_pages = ceil($total_records / $per_page); $offset = ($page-1) * $per_page; /* 结束分页信息 */ $sql = "select * from products limit :offset, :per_page"; $stmt = $pdo->prepare($sql); $stmt->execute(['offset'=>$offset, 'per_page'=>$per_page]); echo "<table border='1' align='center'>"; while ( ($row = $stmt->fetch(PDO::FETCH_ASSOC) ) !== false) { echo "<tr>"; echo "<td>".$row['product_id']."</td>"; echo "<td>".$row['product_name']."</td>"; echo "</tr>"; } echo "</table>"; /* 开始导航 */ echo "<table border='1' align='center'>"; echo "<tr>"; if ($page-1 >= 1) { echo "<td><a href=".$_SERVER['PHP_SELF']."?page=".($page - 1).">上一页</a></td>"; } if ($page+1 <= $total_pages) { echo "<td><a href=".$_SERVER['PHP_SELF']."?page=".($page + 1).">下一页</a></td>"; } echo "</tr>"; echo "</table>"; /* 结束导航 */ } catch(PDOException $e) { echo $e->getMessage(); } ?> |
以下是这段代码的摘要:
-
我们需要保存当前所在页面的信息。为此,我们使用 $page 变量。 $page 变量用于通过 $_GET[‘page’] 变量来提取我们当前所在的页面。
-
接下来,我们需要指定每页显示多少条内容。为此,我们使用 $per_page 变量。在这里,我们每页仅显示三个产品。
-
如上所述,我们需要获取数据库中存在的记录总数。这是为了让我们能够确定总页数。 $total_records 变量保存了这一信息。
-
最后,我们需要知道要跳过多少条记录。例如,如果我们处于第二页,我们需要跳过数据库中的前三条记录。我们正在使用 $offset 变量来保存这一信息。我们在每次加载页面时使用以下公式计算该信息: $offset=($page-1)*$per_page。如果您需要显示任何其他数量的项目,可以在 $per_page 变量中指定该值。
-
要显示导航按钮,我们使用以下代码:
|
1 2 3 4 5 6 7 8 9 10 |
. . . if( $page-1>=1) { echo "<td><a href=".$_SERVER['PHP_SELF']."?page=".($page-1).">上一页</a></td>"; } if( $page+1<=$total_pages) { echo "<td><a href=".$_SERVER['PHP_SELF']."?page=".($page+1).">下一页</a></td>"; } . . . |
其逻辑是, $page 用于保存当前页面。如果我们想在页面上显示“上一页”选项,脚本将从 $page 变量的值中减去 1。如果结果大于或等于 1,则在页面上显示“上一页”选项。
类似地,要显示“下一页”选项,我们将 $page 变量加 1。在这里,我们要确保相加的结果不超过 $total_pages 变量中的总页数。
之后,是时候检查页面了。打开浏览器并使用您之前使用的 URL 导航到该页面:
|
1 |
http://your_server_ip/pagination_test.php |
您将看到如下输出:



至此,您终于在 PHP 脚本中利用 MySQL 的 LIMIT 子句实现了分页。通过在应用程序中实现分页,您将能够更好地在多条记录之间进行导航。
结论
在本教程中,我们学习了如何在 Ubuntu 上使用 PHP 和 MySQL 实现分页。利用这些步骤,您可以构建能够充分显示大量记录的应用程序,并将这些记录划分到各个页面中以便进行有效操作。
此外,我们还有更多关于在 Ubuntu 上使用 PHP 和 MySQL 的实用教程:
- 在 Ubuntu 18.04 上安装和保护 phpMyAdmin
- 如何重置 MariaDB 或 MySQL Root 密码
- CloudSigma 教程:如何在服务器上设置 MySQL 以及 MySQL 基础知识
祝您使用愉快!
评论
暂无评论。发表第一条评论吧。