打造自己的待办事项列表应用
1. 显示数据库内容
首先,有一段原始的 HTML 代码,添加了一个
mysqli
连接对象:
<h1>Pi Todo List App</h1>
<?php
$mysqli = new mysqli('localhost', 'pi', 'raspberry', 'pi');
if ($mysqli->connect_error) {
die('Connect Error (' . $mysqli->connect_errno . ') '
. $mysqli->connect_error);
}
$mysqli->close();
?>
</body>
</html>
若没有错误,这段代码不会有太多显示。接下来,需要添加代码来显示待办事项列表。分为两部分:表格块和表头。以下是基本的 HTML 表格布局:
<table>
<tr>
<th>Description</th>
<th>Owner</th>
<th>Due Date</th>
<th>Location</th>
<th>Importance</th>
<th>Creator</th>
</tr>
...
</table>
此代码设置了表格及其第一行,均标记为表头元素。再添加 PHP 代码来显示 MySQL 表中的所有内容:
<?php
$result = $mysqli->query("SELECT * FROM todolist");
while($row = $result->fetch_assoc()){
print "<tr>";
print "<td>".$row["description"]."</td>";
print "<td>".$row["owner"]."</td>";
print "<td>".$row["date"]."</td>";
print "<td>".$row["location"]."</td>";
print "<td>".$row["importance"]."</td>";
print "<td>".$row["creator"]."</td>";
print "</tr>";
}
?>
PHP 部分的工作流程如下:
1. 创建一个新变量
$result
,它包含执行
mysqli
查询的输出,查询语句是
SELECT * FROM todolist
。
2. 在
while
循环中,通过
$result->fetch_assoc()
调用将结果的每一行逐一传递出来,并赋值给
row
变量。
3. 对于每一行,打印请求的每个字段的行值。
需要将上述代码添加回原始代码块,同时将
$mysqli->close();
移到新块的底部,即在 PHP 段结束之前:
<body>
<h1>Pi Todo List App</h1>
<?php
$mysqli = new mysqli('localhost', 'pi', 'raspberry', 'pi');
if ($mysqli->connect_error) {
die('Connect Error (' . $mysqli->connect_errno . ') '
. $mysqli->connect_error);
}
?>
<table>
<tr>
<th>Description</th>
<th>Owner</th>
<th>Due Date</th>
<th>Location</th>
<th>Importance</th>
<th>Creator</th>
</tr>
<?php
$result = $mysqli->query("SELECT * FROM todolist");
while($row = $result->fetch_assoc()){
print "<tr>";
print "<td>".$row["description"]."</td>";
print "<td>".$row["owner"]."</td>";
print "<td>".$row["date"]."</td>";
print "<td>".$row["location"]."</td>";
print "<td>".$row["importance"]."</td>";
print "<td>".$row["creator"]."</td>";
print "</tr>";
}
$mysqli->close();
?>
</table>
</body>
</html>
2. 网站数据插入
现在 HTML 和 PHP 协同工作,生成完整页面内容。静态 HTML 提供框架,有两段 PHP 代码,一段用于建立连接,另一段从待办事项列表表中提取结果并添加到页面。基本显示功能正常后,需要添加一个表单来提交新内容。基本表单应包含要插入表中的每个元素的输入流,还需要一个特殊的隐藏元素,用于告诉处理器如何处理数据,这里使用变量
action
并按需赋值,最后需要一个提交元素将数据推送到服务器进行处理。表单代码如下:
...
</table>
<form action="index.php" method="POST">
<input type="hidden" name="action" value="insert" />
Description: <input name="description" /><br/>
Owner: <input name="owner" /><br/>
Date: <input name="date" /><br/>
Location: <input name="location" /><br/>
Importance: <input name="importance" /><br/>
Creator: <input name="creator" /><br/>
<input type="submit" />
</form>
</body>
</html>
此代码块可添加到表格下方,甚至可以用
<hr />
标签分隔,这样就有一个显示内容的表格和一个添加新内容的区域。
按下提交按钮后,会回到当前页面,URL 会显示相关信息,这是动作块发送 CGI 命令在当前页面运行。因此需要在 PHP 中添加一些 CGI 处理来处理数据。
之前设置了提交方法为
POST
,还有另一种方法是
GET
。两者区别在于,
GET
会在网页地址中显示内容数据,而
POST
会隐藏数据。可以将
POST
改为
GET
并按下提交按钮进行验证。
PHP 有特殊变量可自动填充 CGI 请求的数据,可访问的三个特殊变量是
_POST
、
_GET
和
_REQUEST
。处理 CGI 的步骤如下:
1. 检查
action
变量是否设置并包含数据。
2. 若
action
已设置,使用
switch
语句确定要执行的操作。
3. 根据操作类型,拆分输出的其余部分并对数据库执行所需操作。
4. 在主页面加载之前执行这些操作,可自动显示最新数据。
CGI 代码如下:
if(isset($_REQUEST["action"])){
switch($_REQUEST["action"]){
case "insert":
$SQL="INSERT INTO todolist (description, owner, date, location, importance, creator)
VALUES (";
$SQL=$SQL."'".$_REQUEST["description"]."',";
$SQL=$SQL."'".$_REQUEST["owner"]."',";
$SQL=$SQL."'".$_REQUEST["date"]."',";
$SQL=$SQL."'".$_REQUEST["location"]."',";
$SQL=$SQL."'".$_REQUEST["importance"]."',";
$SQL=$SQL."'".$_REQUEST["creator"]."'";
$SQL=$SQL.");";
if ($mysqli->query($SQL)=== FALSE) {
printf("Error – Unable to insert data to table " . $mysqli->error);
}
break;
case "delete":
print "Delete function yet to be added!";
break;
}
}
插入数据库的操作步骤
-
创建并构建 SQL 命令,先确定
INSERT语句的框架、表名和要写入的字段。 - 逐个添加变量到语句中,每个变量需用单引号括起来,末尾加逗号。
-
例如:
$SQL=$SQL."'".$_REQUEST["description"]."',";,将当前SQL值与新变量组合。 -
需注意,上述代码不安全,可使用
mysqli_real_escape_string函数对变量进行安全检查。 -
创建
SQL变量后,调用mysqli查询函数插入数据,并检查查询执行是否失败。 - 将此代码块添加到第一个 PHP 块中,页面流程变为:绘制页面标题、创建数据库连接并执行 CGI 操作、显示待办事项列表内容、显示最终表单。
以下是操作流程的 mermaid 流程图:
graph TD;
A[开始] --> B[创建数据库连接];
B --> C{检查action变量是否设置};
C -- 是 --> D{确定action值};
D -- insert --> E[构建插入SQL语句];
E --> F[执行插入操作];
F --> G{插入是否成功};
G -- 是 --> H[显示最新数据];
G -- 否 --> I[输出插入错误信息];
D -- delete --> J[提示删除功能待添加];
C -- 否 --> H;
H --> K[结束];
I --> K;
J --> K;
3. 删除条目
添加功能正常后,需要创建删除功能。有两种方法:
1. 为每一行添加一个表单和删除选项,需逐个删除。
2. 使用一系列复选框,删除所有勾选的元素,这种方法更灵活。
为实现删除功能,需要进行两项更改:
1. 在表格周围添加一个删除表单,包含隐藏字段
action
,值为
delete
,表单下方有提交按钮,为每个元素添加复选框。
2. 在表格表头行的开头添加一个空元素。
以下是添加复选框后的表单代码:
...
<h1>Pi Todo List App</h1>
<form action="index.php" method="POST">
<input type="hidden" name="action" value="delete" />
<table>
<tr>
<td></td>
...
</tr>
<?php
$result = $mysqli->query("SELECT * FROM todolist");
while($row= $result->fetch_assoc()){
print "<tr>";
print "<td><input type='checkbox' name='checkboxes[]' value='".$row["idnumber"]."' /></td>";
print "<td>".$row["description"]."</td>";
print "<td>".$row["owner"]."</td>";
print "<td>".$row["date"]."</td>";
print "<td>".$row["location"]."</td>";
print "<td>".$row["importance"]."</td>";
print "<td>".$row["creator"]."</td>";
print "</tr>";
}
$mysqli->close();
?>
</table>
<input type="submit"/>
</form>
...
从数据库中删除数据
最后,需要在
case
语句中添加删除处理代码。逻辑与插入语句类似,创建一个
SQL
变量,然后迭代添加要删除的
idnumber
。具体步骤如下:
1. 使用
for
循环遍历
_REQUEST['checkboxes']
变量的每个元素。
2. 在循环中,每次取出数组的第
$i
个元素,并在末尾添加
or
。
3. 使用
rtrim
函数去除最后一个
or
。
4. 执行查询操作并检查是否有错误。
删除处理代码如下:
$SQL="DELETE FROM todolist WHERE";
for($i=0; $i < count($_REQUEST['checkboxes']); $i++){
$SQL=$SQL . " idnumber=" . $_REQUEST['checkboxes'][$i] . " or";
}
$SQL= rtrim($SQL, "or");
if ($mysqli->query($SQL)== FALSE) {
printf("Error Unable to delete value " . $mysqli->error);
}
4. 故障排除
在开发过程中,可能会遇到一些问题,可按以下方法进行排查:
1. 按顺序进行代码更改,然后重新加载页面。
2. 使用
view source
命令查看 PHP 生成的完整 HTML,检查值是否正确显示。
3. 若无法正常显示,查看错误日志(配置 Apache 时的日志文件),该文件会列出所有 PHP 错误。
4. 确保引号正确开闭,语句末尾有分号,括号正确匹配且无重叠。
5. PHP 和网页开发很多时候需要反复尝试,可使用
print
语句输出变量,诊断 SQL 语句问题。
6. 可直接测试向 SQL 插入和删除值,了解系统运行情况和问题原因。
5. 后续改进方向
目前已开发出一个功能完整的待办事项列表应用,可进行显示、添加和删除条目操作。后续还可以进行以下改进:
- 为每个插入值添加
isset()
检查,确保插入的不是空白值。
- 使用
mysqli_real_escape_string
函数包装插入值,提高待办事项列表的安全性,防止恶意 SQL 查询。
通过以上步骤,你可以打造一个功能丰富且安全的待办事项列表应用。
打造自己的待办事项列表应用
6. 代码结构总结
为了更清晰地理解整个待办事项列表应用的代码结构,我们可以将其主要部分进行总结,如下表所示:
| 功能模块 | 代码位置 | 主要功能 |
| ---- | ---- | ---- |
| 数据库连接 |
$mysqli = new mysqli('localhost', 'pi', 'raspberry', 'pi');
| 建立与数据库的连接 |
| 数据显示 |
$result = $mysqli->query("SELECT * FROM todolist");
及后续
while
循环 | 从数据库中查询待办事项数据并显示在 HTML 表格中 |
| 数据插入 |
switch
语句中的
case "insert"
| 根据表单提交的数据构建插入 SQL 语句并执行插入操作 |
| 数据删除 |
switch
语句中的
case "delete"
| 根据勾选的复选框构建删除 SQL 语句并执行删除操作 |
7. 详细操作流程梳理
下面我们通过一个更详细的 mermaid 流程图来展示整个应用的操作流程:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px
A([开始]):::startend --> B(创建数据库连接):::process
B --> C{检查是否有 action 请求}:::decision
C -->|有| D{action 值是什么}:::decision
D -->|insert| E(构建插入 SQL 语句):::process
E --> F(执行插入操作):::process
F --> G{插入是否成功}:::decision
G -->|是| I(查询并显示待办事项列表):::process
G -->|否| H(输出插入错误信息):::process
D -->|delete| J(构建删除 SQL 语句):::process
J --> K(执行删除操作):::process
K --> L{删除是否成功}:::decision
L -->|是| I
L -->|否| M(输出删除错误信息):::process
C -->|无| I
H --> N(结束):::startend
M --> N
I --> O(显示插入新事项表单):::process
O --> P(等待用户操作):::process
P -->|提交插入表单| C
P -->|提交删除表单| C
P -->|无操作| Q(页面保持显示):::process
Q --> P
8. 安全性深入分析
在前面提到了使用
mysqli_real_escape_string
函数来提高应用的安全性,下面我们详细说明如何使用该函数。
插入数据时的安全性改进
在插入数据时,对用户输入的数据进行转义处理,示例代码如下:
if(isset($_REQUEST["action"])){
switch($_REQUEST["action"]){
case "insert":
$description = mysqli_real_escape_string($mysqli, $_REQUEST["description"]);
$owner = mysqli_real_escape_string($mysqli, $_REQUEST["owner"]);
$date = mysqli_real_escape_string($mysqli, $_REQUEST["date"]);
$location = mysqli_real_escape_string($mysqli, $_REQUEST["location"]);
$importance = mysqli_real_escape_string($mysqli, $_REQUEST["importance"]);
$creator = mysqli_real_escape_string($mysqli, $_REQUEST["creator"]);
$SQL="INSERT INTO todolist (description, owner, date, location, importance, creator)
VALUES ('$description', '$owner', '$date', '$location', '$importance', '$creator');";
if ($mysqli->query($SQL)=== FALSE) {
printf("Error – Unable to insert data to table " . $mysqli->error);
}
break;
case "delete":
print "Delete function yet to be added!";
break;
}
}
检查插入值是否为空
为了避免插入空白数据,在插入操作前添加
isset()
检查,代码如下:
if(isset($_REQUEST["action"])){
switch($_REQUEST["action"]){
case "insert":
if(isset($_REQUEST["description"]) && !empty($_REQUEST["description"]) &&
isset($_REQUEST["owner"]) && !empty($_REQUEST["owner"]) &&
isset($_REQUEST["date"]) && !empty($_REQUEST["date"]) &&
isset($_REQUEST["location"]) && !empty($_REQUEST["location"]) &&
isset($_REQUEST["importance"]) && !empty($_REQUEST["importance"]) &&
isset($_REQUEST["creator"]) && !empty($_REQUEST["creator"])) {
$description = mysqli_real_escape_string($mysqli, $_REQUEST["description"]);
$owner = mysqli_real_escape_string($mysqli, $_REQUEST["owner"]);
$date = mysqli_real_escape_string($mysqli, $_REQUEST["date"]);
$location = mysqli_real_escape_string($mysqli, $_REQUEST["location"]);
$importance = mysqli_real_escape_string($mysqli, $_REQUEST["importance"]);
$creator = mysqli_real_escape_string($mysqli, $_REQUEST["creator"]);
$SQL="INSERT INTO todolist (description, owner, date, location, importance, creator)
VALUES ('$description', '$owner', '$date', '$location', '$importance', '$creator');";
if ($mysqli->query($SQL)=== FALSE) {
printf("Error – Unable to insert data to table " . $mysqli->error);
}
} else {
printf("Error – Please fill in all fields.");
}
break;
case "delete":
print "Delete function yet to be added!";
break;
}
}
9. 性能优化建议
除了安全性,性能也是一个重要的方面。以下是一些性能优化的建议:
-
数据库索引
:在
todolist
表的常用查询字段(如
idnumber
、
date
等)上创建索引,可以加快查询速度。例如,在 MySQL 中可以使用以下语句创建索引:
CREATE INDEX idx_idnumber ON todolist (idnumber);
CREATE INDEX idx_date ON todolist (date);
-
分页显示
:如果待办事项列表数据量较大,可采用分页显示的方式,减少一次性查询和显示的数据量。可以通过修改 SQL 查询语句,使用
LIMIT和OFFSET关键字实现分页,示例代码如下:
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$limit = 10; // 每页显示 10 条记录
$offset = ($page - 1) * $limit;
$result = $mysqli->query("SELECT * FROM todolist LIMIT $offset, $limit");
while($row = $result->fetch_assoc()){
// 显示数据
}
10. 总结
通过以上步骤,我们成功打造了一个功能丰富的待办事项列表应用,包括数据的显示、插入和删除功能。同时,我们还对应用的安全性和性能进行了深入分析,并给出了相应的改进建议。在实际开发中,我们可以根据具体需求进一步扩展和优化这个应用,例如添加更多的字段、实现排序功能、优化用户界面等。希望本文能对你开发类似的应用有所帮助。
超级会员免费看

被折叠的 条评论
为什么被折叠?



