凌峰创科服务平台

PHP网站开发实例教程如何快速上手?

目标:构建一个简单的博客系统

我们将创建一个包含以下功能的博客网站:

PHP网站开发实例教程如何快速上手?-图1
(图片来源网络,侵删)
  1. 首页:展示所有博客文章列表。
  2. 文章详情页:点击文章标题,查看文章的完整内容。
  3. 后台管理
    • 登录功能。
    • 发布新文章。
    • 编辑现有文章。
    • 删除文章。

第一步:环境准备

在开始之前,你需要一个本地的 PHP 开发环境,最简单的方式是使用集成环境包。

推荐工具:XAMPP

XAMPP 是一个集成了 Apache (Web服务器)、MySQL (数据库) 和 PHP 的免费软件包。

  1. 下载:访问 XAMPP 官网,下载适合你操作系统的版本。
  2. 安装:按照安装向导完成安装,记住安装路径,通常是 C:\xampp (Windows) 或 /Applications/XAMPP (macOS)。
  3. 启动服务
    • 打开 XAMPP Control Panel。
    • 点击 ApacheMySQL 模块的 Start 按钮。
  4. 验证:在浏览器中访问 http://localhosthttp://127.0.0.1,如果你能看到 XAMPP 的欢迎页面,说明环境已成功搭建。

创建项目目录

  1. 在 XAMPP 的安装目录下,找到 htdocs 文件夹。
  2. htdocs 文件夹中创建一个新文件夹,命名为 my_blog
  3. 这个 my_blog 文件夹就是我们的网站根目录,之后所有代码都放在这里。

第二步:数据库设计与创建

我们的博客需要一个数据库来存储文章和用户信息。

  1. 访问 phpMyAdmin:在浏览器中访问 http://localhost/phpmyadmin
  2. 创建数据库
    • 在主页面的 "创建数据库" 输入框中,输入 my_blog_db
    • 选择排序规则(通常使用 utf8mb4_general_ci 以支持中文和 Emoji)。
    • 点击 "创建"。
  3. 创建数据表
    • 在左侧选择刚创建的 my_blog_db
    • 在 "在数据库 my_blog_db 中创建表" 输入框中,输入 posts
    • 设置字段数为 4,然后点击 "执行"。
    • 填写 posts 表结构
      • id: 类型选 INT,勾选 A_I (Auto Increment,自增) 作为主键。
      • title: 类型 VARCHAR(255),长度 255。
      • content: 类型 TEXT,用于存储长文本。
      • created_at: 类型 DATETIME,用于记录创建时间。
    • 点击 "保存"。
  4. 创建用户表
    • 再次在 "在数据库 my_blog_db 中创建表" 输入框中,输入 users
    • 设置字段数为 3,然后点击 "执行"。
    • 填写 users 表结构
      • id: 类型 INT,勾选 A_I 作为主键。
      • username: 类型 VARCHAR(50),长度 50。
      • password: 类型 VARCHAR(255)长度一定要足够长,因为我们会存储哈希后的密码。
    • 点击 "保存"。
  5. 插入一个管理员用户
    • users 表页,点击 "插入" 标签页。
    • username 填入 admin
    • password 填入 123456 (这只是明文,我们稍后会用 PHP 代码来正确地创建一个哈希密码)。
    • 点击 "执行"。

第三步:项目结构与基础文件

my_blog 文件夹中,我们创建以下结构来组织代码:

PHP网站开发实例教程如何快速上手?-图2
(图片来源网络,侵删)
my_blog/
├── assets/
│   ├── css/
│   │   └── style.css         # 存放样式文件
│   └── images/
├── config/
│   └── database.php          # 数据库连接配置
├── admin/
│   ├── login.php             # 管理员登录页
│   ├── dashboard.php         # 管理后台首页
│   ├── create_post.php       # 创建文章页面
│   └── edit_post.php         # 编辑文章页面
├── includes/
│   ├── header.php            # 公共头部
│   └── footer.php            # 公共底部
├── index.php                 # 博客首页
├── post.php                  # 文章详情页
└── .htaccess                 # URL 重写规则 (可选,但推荐)

第四步:编写核心代码

数据库连接 (config/database.php)

这是一个非常重要的文件,我们把它单独拿出来,方便以后修改数据库信息而不用改动其他文件。

<?php
// config/database.php
$host = 'localhost';
$db_name = 'my_blog_db';
$username = 'root'; // XAMPP 默认用户名
$password = '';     // XAMPP 默认密码为空
try {
    $pdo = new PDO("mysql:host={$host};dbname={$db_name}", $username, $password);
    // 设置 PDO 错误模式为异常
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
    die("连接失败: " . $e->getMessage());
}
?>

公共头部 (includes/header.php)

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">我的博客</title>
    <link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
    <header>
        <h1><a href="index.php">我的博客</a></h1>
        <nav>
            <a href="index.php">首页</a>
            <a href="admin/login.php">管理后台</a>
        </nav>
    </header>
    <div class="container">

公共底部 (includes/footer.php)

    </div> <!-- .container -->
    <footer>
        <p>&copy; <?php echo date('Y'); ?> 我的博客. All rights reserved.</p>
    </footer>
</body>
</html>

博客首页 (index.php)

展示文章列表。

<?php
require_once 'config/database.php';
require_once 'includes/header.php';
// 从数据库获取文章
try {
    $stmt = $pdo->query("SELECT id, title, created_at FROM posts ORDER BY created_at DESC");
    $posts = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
    die("获取文章失败: " . $e->getMessage());
}
?>
<h2>最新文章</h2>
<?php if (empty($posts)): ?>
    <p>暂无文章。</p>
<?php else: ?>
    <ul class="post-list">
        <?php foreach ($posts as $post): ?>
            <li>
                <a href="post.php?id=<?php echo htmlspecialchars($post['id']); ?>">
                    <?php echo htmlspecialchars($post['title']); ?>
                </a>
                <span class="post-date"><?php echo date('Y-m-d', strtotime($post['created_at'])); ?></span>
            </li>
        <?php endforeach; ?>
    </ul>
<?php endif; ?>
<?php require_once 'includes/footer.php'; ?>

文章详情页 (post.php)

显示单篇文章的完整内容。

<?php
require_once 'config/database.php';
require_once 'includes/header.php';
$post_id = $_GET['id'] ?? null;
if (!$post_id) {
    die('文章 ID 未指定。');
}
try {
    $stmt = $pdo->prepare("SELECT * FROM posts WHERE id = ?");
    $stmt->execute([$post_id]);
    $post = $stmt->fetch(PDO::FETCH_ASSOC);
    if (!$post) {
        die('文章不存在。');
    }
} catch (PDOException $e) {
    die("获取文章失败: " . $e->getMessage());
}
?>
<h1><?php echo htmlspecialchars($post['title']); ?></h1>
<p class="post-meta">发布于: <?php echo date('Y-m-d H:i:s', strtotime($post['created_at'])); ?></p>
<hr>
<div class="post-content">
    <?php 
    // nl2br 函数将换行符转换为 <br> 标签,使文本在 HTML 中正确换行
    echo nl2br(htmlspecialchars($post['content'])); 
    ?>
</div>
<?php require_once 'includes/footer.php'; ?>

第五步:实现后台管理功能

管理员登录 (admin/login.php)

<?php
session_start(); // 必须在所有输出之前调用
// 如果已经登录,直接跳转到后台
if (isset($_SESSION['admin_logged_in']) && $_SESSION['admin_logged_in'] === true) {
    header('Location: dashboard.php');
    exit;
}
require_once '../config/database.php';
$error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $username = $_POST['username'] ?? '';
    $password = $_POST['password'] ?? '';
    // 注意:在实际应用中,密码应该是哈希后存储和比较的
    // 这里为了简化,直接比较明文。**不推荐在生产环境中使用!**
    $stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
    $stmt->execute([$username, $password]);
    $user = $stmt->fetch(PDO::FETCH_ASSOC);
    if ($user) {
        // 登录成功,设置 session
        $_SESSION['admin_logged_in'] = true;
        $_SESSION['admin_username'] = $user['username'];
        header('Location: dashboard.php');
        exit;
    } else {
        $error = '用户名或密码错误。';
    }
}
?>
<?php require_once '../includes/header.php'; ?>
<h2>管理员登录</h2>
<?php if ($error): ?>
    <p class="error"><?php echo $error; ?></p>
<?php endif; ?>
<form action="login.php" method="POST" class="login-form">
    <div>
        <label for="username">用户名:</label>
        <input type="text" id="username" name="username" required>
    </div>
    <div>
        <label for="password">密码:</label>
        <input type="password" id="password" name="password" required>
    </div>
    <button type="submit">登录</button>
</form>
<?php require_once '../includes/footer.php'; ?>

后台首页 (admin/dashboard.php)

<?php
session_start();
// 检查是否已登录,如果未登录则跳转到登录页
if (!isset($_SESSION['admin_logged_in']) || $_SESSION['admin_logged_in'] !== true) {
    header('Location: login.php');
    exit;
}
require_once '../config/database.php';
require_once '../includes/header.php';
?>
<h2>欢迎, <?php echo htmlspecialchars($_SESSION['admin_username']); ?>!</h2>
<p>这是管理后台。</p>
<ul>
    <li><a href="create_post.php">发布新文章</a></li>
    <li><a href="edit_post.php">编辑文章</a></li>
    <li><a href="../index.php">返回博客首页</a></li>
    <li><a href="logout.php">退出登录</a></li>
</ul>
<?php require_once '../includes/footer.php'; ?>

退出登录 (admin/logout.php)

<?php
session_start();
// 销毁所有 session 变量
session_unset();
// 销毁 session
session_destroy();
// 重定向到登录页
header('Location: login.php');
exit;
?>

创建文章 (admin/create_post.php)

<?php
session_start();
if (!isset($_SESSION['admin_logged_in']) || $_SESSION['admin_logged_in'] !== true) {
    header('Location: login.php');
    exit;
}
require_once '../config/database.php';
require_once '../includes/header.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $title = $_POST['title'] ?? '';
    $content = $_POST['content'] ?? '';
    if (!empty($title) && !empty($content)) {
        try {
            $stmt = $pdo->prepare("INSERT INTO posts (title, content, created_at) VALUES (?, ?, NOW())");
            $stmt->execute([$title, $content]);
            echo "<p class='success'>文章发布成功!</p>";
            // 清空表单
            $title = '';
            $content = '';
        } catch (PDOException $e) {
            echo "<p class='error'>发布失败: " . $e->getMessage() . "</p>";
        }
    } else {
        echo "<p class='error'>标题和内容都不能为空!</p>";
    }
}
?>
<h2>发布新文章</h2>
<form action="create_post.php" method="POST" class="post-form">
    <div>
        <label for="title">标题:</label>
        <input type="text" id="title" name="title" value="<?php echo htmlspecialchars($title ?? ''); ?>" required>
    </div>
    <div>
        <label for="content">内容:</label>
        <textarea id="content" name="content" rows="10" required><?php echo htmlspecialchars($content ?? ''); ?></textarea>
    </div>
    <button type="submit">发布</button>
</form>
<?php require_once '../includes/footer.php'; ?>

编辑文章 (admin/edit_post.php)

这个页面需要先获取现有文章内容,然后允许修改。

PHP网站开发实例教程如何快速上手?-图3
(图片来源网络,侵删)
<?php
session_start();
if (!isset($_SESSION['admin_logged_in']) || $_SESSION['admin_logged_in'] !== true) {
    header('Location: login.php');
    exit;
}
require_once '../config/database.php';
require_once '../includes/header.php';
$post_id = $_GET['id'] ?? null;
$post = null;
if ($post_id) {
    try {
        $stmt = $pdo->prepare("SELECT * FROM posts WHERE id = ?");
        $stmt->execute([$post_id]);
        $post = $stmt->fetch(PDO::FETCH_ASSOC);
    } catch (PDOException $e) {
        die("获取文章失败: " . $e->getMessage());
    }
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $post_id) {
    $title = $_POST['title'] ?? '';
    $content = $_POST['content'] ?? '';
    if (!empty($title) && !empty($content)) {
        try {
            $stmt = $pdo->prepare("UPDATE posts SET title = ?, content = ? WHERE id = ?");
            $stmt->execute([$title, $content, $post_id]);
            echo "<p class='success'>文章更新成功!</p>";
            // 刷新页面以显示新内容
            header("Refresh: 2; URL=edit_post.php?id=$post_id");
        } catch (PDOException $e) {
            echo "<p class='error'>更新失败: " . $e->getMessage() . "</p>";
        }
    } else {
        echo "<p class='error'>标题和内容都不能为空!</p>";
    }
}
?>
<h2>编辑文章</h2>
<?php if ($post): ?>
    <form action="edit_post.php?id=<?php echo $post['id']; ?>" method="POST" class="post-form">
        <div>
            <label for="title">标题:</label>
            <input type="text" id="title" name="title" value="<?php echo htmlspecialchars($post['title']); ?>" required>
        </div>
        <div>
            <label for="content">内容:</label>
            <textarea id="content" name="content" rows="10" required><?php echo htmlspecialchars($post['content']); ?></textarea>
        </div>
        <button type="submit">更新</button>
    </form>
<?php else: ?>
    <p>未找到要编辑的文章。</p>
<?php endif; ?>
<?php require_once '../includes/footer.php'; ?>

第六步:添加一些 CSS 样式 (assets/css/style.css)

为了让网站看起来更美观,添加一些简单的 CSS。

/* assets/css/style.css */
body {
    font-family: Arial, sans-serif;
    line-height: 1.6;
    margin: 0;
    background-color: #f4f4f4;
    color: #333;
}
.container {
    max-width: 800px;
    margin: 20px auto;
    padding: 0 20px;
    background: #fff;
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
header {
    background: #333;
    color: #fff;
    padding: 1rem 0;
    text-align: center;
}
header h1 a {
    color: #fff;
    text-decoration: none;
}
nav a {
    color: #fff;
    margin: 0 15px;
    text-decoration: none;
}
nav a:hover {
    text-decoration: underline;
}
.post-list {
    list-style: none;
    padding: 0;
}
.post-list li {
    background: #f9f9f9;
    border: 1px solid #ddd;
    padding: 15px;
    margin-bottom: 10px;
    border-radius: 5px;
}
.post-list a {
    color: #0066cc;
    text-decoration: none;
    font-weight: bold;
    font-size: 1.2em;
}
.post-list a:hover {
    text-decoration: underline;
}
.post-date {
    float: right;
    color: #777;
    font-size: 0.9em;
}
.post-meta {
    color: #777;
    font-size: 0.9em;
}
.post-content {
    margin-top: 20px;
    white-space: pre-wrap; /* 保留空格和换行 */
}
.login-form, .post-form {
    max-width: 400px;
    margin: 20px auto;
    padding: 20px;
    background: #f9f9f9;
    border-radius: 5px;
}
.login-form div, .post-form div {
    margin-bottom: 15px;
}
.login-form label, .post-form label {
    display: block;
    margin-bottom: 5px;
}
.login-form input, .post-form input, .post-form textarea {
    width: 100%;
    padding: 8px;
    border: 1px solid #ddd;
    border-radius: 4px;
    box-sizing: border-box; /* 确保 padding 不会影响宽度 */
}
.login-form button, .post-form button {
    background: #333;
    color: #fff;
    padding: 10px 15px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}
.login-form button:hover, .post-form button:hover {
    background: #555;
}
.error {
    color: #D8000C;
    background-color: #FFD2D2;
    padding: 10px;
    border-radius: 5px;
    margin: 10px 0;
}
.success {
    color: #4F8A10;
    background-color: #DFF2BF;
    padding: 10px;
    border-radius: 5px;
    margin: 10px 0;
}
footer {
    text-align: center;
    padding: 20px;
    margin-top: 20px;
    color: #777;
}

总结与进阶

恭喜!你已经成功创建了一个功能完整的 PHP 博客网站,这个项目涵盖了 PHP 开发中最常用的几个方面:

  • MVC 思想雏形:虽然我们没有严格使用 MVC 框架,但已经将数据、视图和控制逻辑(PHP 脚本)分离开来。
  • 数据库交互:使用 PDO 安全地连接和查询 MySQL 数据库。
  • 会话管理:使用 $_SESSION 实现用户登录状态。
  • 表单处理:接收和处理用户提交的数据。
  • 安全性基础:使用 htmlspecialchars() 防止 XSS 攻击。

可以继续改进的方向:

  1. 密码哈希:在 admin/login.php 中,将明文密码改为使用 password_hash()password_verify() 函数。
  2. 文章删除功能:在 dashboard.phpedit_post.php 中添加删除按钮。
  3. 分页:当文章很多时,首页需要分页显示。
  4. URL 友好化:使用 .htaccessmod_rewritepost.php?id=1 变成 post/my-first-post 这样的友好 URL。
  5. 使用框架:学习并使用 Laravel 或 Symfony 等现代 PHP 框架,它们能让你更高效、更规范地开发大型应用。
  6. 增加评论功能:创建一个 comments 表,并为每篇文章添加评论功能。

这个教程是一个绝佳的起点,希望它能帮助你迈出 PHP Web 开发的第一步!

分享:
扫描分享到社交APP
上一篇
下一篇