🇯🇵 日本語 | 🇺🇸 English | 🇪🇸 Español | 🇵🇹 Português | 🇹🇭 ไทย | 🇨🇳 中文

【PHP入门】开发动态Web应用!结合数据库制作一句话留言板

在之前的文章中,我们学习了PHP的语法以及如何从数据库获取并显示数据。但是,Web应用程序真正的乐趣在于用户能够“添加”或“删除”数据,实现双向互动。这种“由用户操作数据”的功能,可以说是所有Web服务的核心。

在本文中,我们将动员所有至今学到的知识,开发一个与数据库联动的真正的Web应用程序——一句话留言板。这个留言板具备了Web应用最基本的三个功能:发布留言(Create)、列表显示(Read)和删除(Delete)。代码会稍微长一些,但只要将这一个文件复制粘贴到您的服务器上运行,一个属于您自己的“可运行的Web应用程序”就完成了。请务必体验一下编程带来的巨大成就感!

要准备运行PHP(开发环境),如果还没有搭建XAMPP的朋友,请参考【PHP入门】XAMPP下载及安装方法完全解析!。 安装后,将PHP文件放置在指定文件夹(如 `htdocs`)中,准备工作就完成了!

1. CRUD:Web应用程序的基本设计

我们平时使用的SNS、博客、电商网站等Web应用程序,基本上都是由四种数据操作构成的。取其首字母,称之为CRUD

这次我们从中实现除编辑(Update)外的C、R、D三个功能,迈出Web应用程序开发的第一步。

2. 实践!开发一句话留言板

那么,我们马上开始吧。仅用一个PHP文件,就能实现发布、显示、删除的所有功能。

步骤A:准备数据库和数据表

首先,需要创建一个用于保存留言的`memos`表。请在phpMyAdmin等数据库管理工具中执行以下SQL语句。

CREATE TABLE memos (
  id INT AUTO_INCREMENT PRIMARY KEY,
  content VARCHAR(255) NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 插入一些示例数据
INSERT INTO memos (content) VALUES
('开始学习PHP'),
('考虑今晚的菜单'),
('制作周末购物清单');

步骤B:实现所有功能的PHP文件

从这里开始是正题。请将以下代码保存为`memo.php`等文件名。数据库连接信息、数据添加逻辑、删除逻辑以及显示逻辑全都集中在这一个文件里。

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>一句话留言板</title>
    <style>
        body { font-family: sans-serif; padding: 20px; max-width: 700px; margin: auto; background-color: #f9f9f9; }
        h1, h2 { color: #333; border-bottom: 2px solid #007bff; padding-bottom: 10px; }
        .memo-form { background: #fff; padding: 20px; border-radius: 8px; margin-bottom: 30px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
        textarea { width: 100%; height: 60px; padding: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; margin-bottom: 10px; }
        button { padding: 10px 20px; border: none; background-color: #28a745; color: white; border-radius: 4px; cursor: pointer; }
        button:hover { background-color: #218838; }
        .memo-list { list-style: none; padding: 0; }
        .memo-item { background: #fff; padding: 15px; border-left: 5px solid #007bff; margin-bottom: 15px; display: flex; justify-content: space-between; align-items: center; box-shadow: 0 2px 4px rgba(0,0,0,0.05); }
        .memo-content { flex-grow: 1; }
        .memo-date { font-size: 0.8em; color: #888; display: block; margin-top: 5px; }
        .delete-btn { background-color: #dc3545; }
        .delete-btn:hover { background-color: #c82333; }
        .error-message { color: red; font-weight: bold; }
    </style>
</head>
<body>
    <h1>一句话留言板</h1>

    <?php
    // --- 数据库连接信息 ---
    $db_host = 'localhost';
    $db_name = 'your_database_name';
    $db_user = 'your_username';
    $db_pass = 'your_password';

    try {
        $pdo = new PDO("mysql:host={$db_host};dbname={$db_name};charset=utf8", $db_user, $db_pass);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        // --- 数据处理 (当有POST请求时) ---
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            if (isset($_POST['action']) && $_POST['action'] === 'add') {
                // 【Create】添加留言的处理
                if (!empty($_POST['content'])) {
                    $stmt = $pdo->prepare("INSERT INTO memos (content) VALUES (:content)");
                    $stmt->execute([':content' => $_POST['content']]);
                }
            } elseif (isset($_POST['action']) && $_POST['action'] === 'delete') {
                // 【Delete】删除留言的处理
                if (isset($_POST['id'])) {
                    $stmt = $pdo->prepare("DELETE FROM memos WHERE id = :id");
                    $stmt->execute([':id' => $_POST['id']]);
                }
            }
            // 处理后重定向到自身,防止重复提交
            header('Location: ' . $_SERVER['SCRIPT_NAME']);
            exit;
        }

        // --- 数据显示 (当为GET请求时) ---
        // 【Read】获取留言列表
        $stmt = $pdo->prepare("SELECT * FROM memos ORDER BY created_at DESC");
        $stmt->execute();
        $memos = $stmt->fetchAll(PDO::FETCH_ASSOC);

    } catch (PDOException $e) {
        echo '<div class="error-message">数据库错误: ' . htmlspecialchars($e->getMessage()) . '</div>';
        die(); // 发生错误时终止处理
    }
    ?>

    <!-- 留言发布表单 -->
    <section class="memo-form">
        <h2>发布新留言</h2>
        <form action="" method="POST">
            <input type="hidden" name="action" value="add">
            <textarea name="content" required></textarea>
            <button type="submit">发布</button>
        </form>
    </section>

    <!-- 留言列表显示 -->
    <section>
        <h2>留言列表</h2>
        <ul class="memo-list">
            <?php if ($memos): ?>
                <?php foreach ($memos as $memo): ?>
                    <li class="memo-item">
                        <div class="memo-content">
                            <?php echo htmlspecialchars($memo['content']); ?>
                            <span class="memo-date">(<?php echo $memo['created_at']; ?>)</span>
                        </div>
                        <form action="" method="POST" style="display:inline;">
                            <input type="hidden" name="action" value="delete">
                            <input type="hidden" name="id" value="<?php echo $memo['id']; ?>">
                            <button type="submit" class="delete-btn">删除</button>
                        </form>
                    </li>
                <?php endforeach; ?>
            <?php else: ?>
                <li>还没有留言。</li>
            <?php endif; ?>
        </ul>
    </section>

</body>
</html>

重要:在运行此代码前,请不要忘记根据您自己的环境设置来修改数据库连接信息。

怎么样?您应该能确认整个操作流程:从表单发布留言后,它会实时添加到列表中;按下删除按钮后,该留言就会消失。这就是Web应用程序开发的基本CRUD操作(本次为CRD)。

3. 代码解说与要点

这一个文件里包含了几个重要的技巧。

用一个文件处理所有功能的机制

这个应用在同一个文件中处理数据发送(POST)和页面显示(GET)。它使用`if ($_SERVER['REQUEST_METHOD'] === 'POST')`来统一处理“表单被提交时”的操作。无论是添加还是删除,都作为POST请求来接收,处理完毕后重定向到它自身。这是一种被称为**Post/Redirect/Get (PRG) 模式**的技巧,可以有效防止因按下浏览器刷新按钮而导致相同数据被重复提交的“二次提交”问题。

活用hidden类型的input标签

发布表单和删除按钮都通过POST向同一个文件发送数据。为了区分想要执行哪种处理,我们使用了`<input type="hidden">`。

<!-- 发布表单侧 -->
<input type="hidden" name="action" value="add">

<!-- 删除表单侧 -->
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="<?php echo $memo['id']; ?>">

就这样,通过将“`action`(是什么操作)”和“`id`(针对哪条留言)”等不在屏幕上显示的隐藏数据一同发送,PHP端就可以根据接收到的数据来执行适当的处理(添加或删除)。

4. 总结与后续步骤

辛苦了!这次,我们创建了一个与数据库联动,并具备数据创建(Create)、读取(Read)、删除(Delete)功能的动态Web应用“一句话留言板”。亲身体验自己写的代码在浏览器上作为“应用”实际运行起来,想必会带给你巨大的自信吧。

这种CRUD的思路是所有Web应用程序的基础。以此为起点,还可以进一步扩展功能,例如:

请务必以这次的留言板为基础,挑战开发属于你自己的原创应用程序!