项目概述
这是一个简单的PHP WAP网站,用于展示文章列表和文章详情,它具有以下特点:

- 响应式设计:使用 Bootstrap 5 框架,可以完美适配手机、平板和桌面设备。
- 清晰的目录结构:遵循基本的 MVC(Model-View-Controller)模式,便于维护和扩展。
- 安全的数据库操作:使用 PDO (PHP Data Objects) 进行数据库连接和查询,有效防止SQL注入。
- 移动端优化:使用了移动端优先的 Meta 标签和 Bootstrap 的移动组件,提供流畅的触摸体验。
- 代码注释:关键代码部分都附有中文注释,方便理解。
环境要求
- PHP 7.4 或更高版本
- MySQL 5.7 或更高版本
- Web 服务器 (如 Apache 或 Nginx)
- 现代浏览器(推荐 Chrome, Firefox, Safari)
目录结构
为了保持项目整洁,我们创建以下目录结构:
wap-php-source/
├── assets/ # 存放静态资源(CSS, JS, 图片等)
│ ├── css/
│ │ └── style.css # 自定义样式
│ ├── js/
│ │ └── main.js # 自定义脚本
│ └── images/
│ └── logo.png # 网站Logo
├── config/ # 配置文件
│ └── database.php # 数据库连接配置
├── models/ # 数据模型 (M)
│ └── Article.php # 文章数据模型
├── controllers/ # 控制器 (C)
│ ├── HomeController.php # 首页控制器
│ └── ArticleController.php # 文章控制器
├── views/ # 视图文件 (V)
│ ├── layouts/
│ │ └── header.php # 公共头部
│ ├── home/
│ │ └── index.php # 首页视图
│ └── article/
│ └── detail.php # 文章详情页视图
├── index.php # 前端控制器 (入口文件)
└── .htaccess # Apache URL重写规则
代码实现
1. 数据库准备
在你的MySQL数据库中执行以下SQL语句,创建一个数据库和一张文章表。
-- 创建数据库 (数据库名可自定义)
CREATE DATABASE wap_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 使用新创建的数据库
USE wap_db;
-- 创建文章表
CREATE TABLE `articles` (
`id` int(11) NOT NULL AUTO_INCREMENT, varchar(255) NOT NULL,
`content` text NOT NULL,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 插入一些示例数据
INSERT INTO `articles` (`title`, `content`) VALUES
('欢迎使用我们的WAP网站', '这是一个使用PHP和Bootstrap构建的移动友好型网站示例,您可以在这里阅读文章,体验流畅的移动端浏览体验。'),
('PHP开发小技巧', '在开发PHP应用时,使用PDO可以大大提高数据库操作的安全性和灵活性,记得始终对用户输入进行过滤和验证。'),
('响应式网页设计', '响应式设计是现代网页开发的必备技能,它能让你的网站在各种尺寸的设备上都能完美显示,提供一致的用户体验。');
2. 配置文件
config/database.php
配置数据库连接信息。
<?php
// config/database.php
// 定义数据库连接参数
define('DB_HOST', 'localhost');
define('DB_NAME', 'wap_db'); // 修改为你的数据库名
define('DB_USER', 'root'); // 修改为你的数据库用户名
define('DB_PASS ''); // 修改为你的数据库密码
// 创建PDO实例
try {
$pdo = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4", DB_USER, DB_PASS);
// 设置PDO错误模式为异常
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
// 在生产环境中,不应直接显示错误信息
die("数据库连接失败: " . $e->getMessage());
}
3. 模型层
models/Article.php
负责处理所有与文章相关的数据逻辑。

<?php
// models/Article.php
// 引入数据库连接
require_once __DIR__ . '/../config/database.php';
class Article {
// 获取所有文章
public static function getAll() {
global $pdo;
$stmt = $pdo->query("SELECT id, title, created_at FROM articles ORDER BY created_at DESC");
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// 根据ID获取单篇文章
public static function getById($id) {
global $pdo;
$stmt = $pdo->prepare("SELECT * FROM articles WHERE id = ?");
$stmt->execute([$id]);
return $stmt->fetch(PDO::FETCH_ASSOC);
}
}
4. 控制器层
controllers/HomeController.php
处理首页的逻辑。
<?php
// controllers/HomeController.php
require_once __DIR__ . '/../models/Article.php';
class HomeController {
// 显示首页
public function index() {
// 获取所有文章数据
$articles = Article::getAll();
// 加载首页视图并传递数据
include __DIR__ . '/../views/home/index.php';
}
}
controllers/ArticleController.php
处理文章详情页的逻辑。
<?php
// controllers/ArticleController.php
require_once __DIR__ . '/../models/Article.php';
class ArticleController {
// 显示文章详情
public function detail($id) {
// 获取指定ID的文章
$article = Article::getById($id);
// 如果文章不存在,可以跳转到404页面或首页
if (!$article) {
// 简单处理:重定向到首页
header('Location: /index.php');
exit;
}
// 加载文章详情视图并传递文章数据
include __DIR__ . '/../views/article/detail.php';
}
}
5. 视图层
views/layouts/header.php
网站的公共头部,包含导航和必要的CSS/JS引入。
<?php
// views/layouts/header.php
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">PHP WAP网站</title>
<!-- 引入 Bootstrap 5 CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- 引入自定义CSS -->
<link rel="stylesheet" href="/assets/css/style.css">
</head>
<body>
<!-- 导航栏 -->
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container">
<a class="navbar-brand" href="/">PHP WAP</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link active" href="/">首页</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container mt-4">
views/home/index.php
首页视图,用于展示文章列表。

<?php
// views/home/index.php
// 引入头部
require_once __DIR__ . '/../layouts/header.php';
?>
<div class="d-flex justify-content-between align-items-center mb-4">
<h1>最新文章</h1>
</div>
<div class="list-group">
<?php if (!empty($articles)): ?>
<?php foreach ($articles as $article): ?>
<a href="/index.php?page=article&id=<?php echo $article['id']; ?>" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1"><?php echo htmlspecialchars($article['title']); ?></h5>
<small><?php echo date('Y-m-d', strtotime($article['created_at'])); ?></small>
</div>
</a>
<?php endforeach; ?>
<?php else: ?>
<p class="text-center text-muted">暂无文章。</p>
<?php endif; ?>
</div>
<?php
// 引入页脚
require_once __DIR__ . '/../layouts/footer.php';
?>
views/article/detail.php
文章详情页视图。
<?php
// views/article/detail.php
// 引入头部
require_once __DIR__ . '/../layouts/header.php';
?>
<a href="/" class="btn btn-outline-secondary mb-3">
<i class="bi bi-arrow-left"></i> 返回列表
</a>
<div class="card">
<div class="card-body">
<h1 class="card-title"><?php echo htmlspecialchars($article['title']); ?></h1>
<p class="text-muted small">发布于: <?php echo date('Y-m-d H:i', strtotime($article['created_at'])); ?></p>
<hr>
<div class="card-text">
<?php
// 简单的 nl2br 将换行符转换为 <br>
echo nl2br(htmlspecialchars($article['content']));
?>
</div>
</div>
</div>
<?php
// 引入页脚
require_once __DIR__ . '/../layouts/footer.php';
?>
views/layouts/footer.php
网站的公共底部。
<?php
// views/layouts/footer.php
?>
</div> <!-- /.container -->
<!-- 引入 Bootstrap 5 JS 和 Popper.js -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<!-- 引入自定义JS -->
<script src="/assets/js/main.js"></script>
</body>
</html>
6. 前端控制器与路由
index.php
这是整个应用的入口文件,负责解析URL并分发请求到相应的控制器。
<?php
// index.php
// 开启会话 (如果需要)
session_start();
// 定义基础路径
define('BASE_PATH', __DIR__);
// 自动加载类
spl_autoload_register(function ($class_name) {
$file = BASE_PATH . '/controllers/' . $class_name . '.php';
if (file_exists($file)) {
require_once $file;
}
});
// 获取URL参数
$page = $_GET['page'] ?? 'home';
$id = $_GET['id'] ?? null;
// 简单的路由分发
switch ($page) {
case 'home':
$controller = new HomeController();
$controller->index();
break;
case 'article':
if ($id) {
$controller = new ArticleController();
$controller->detail($id);
} else {
// 如果没有ID,重定向到首页
header('Location: /index.php');
exit;
}
break;
default:
// 404 处理
http_response_code(404);
echo "<h1>404 - 页面未找到</h1>";
break;
}
.htaccess
用于实现URL重写,隐藏 index.php,让URL更美观。
# 开启重写引擎
RewriteEngine On
# 如果请求的不是真实存在的文件或目录,则重写到 index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?page=$1 [QSA,L]
7. 静态资源
assets/css/style.css
添加一些自定义样式。
/* assets/css/style.css */
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background-color: #f8f9fa;
}
.list-group-item-action {
border-radius: 8px !important;
margin-bottom: 8px;
transition: all 0.2s ease-in-out;
}
.list-group-item-action:hover {
background-color: #e9ecef;
transform: translateX(5px);
}
.card {
border: none;
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
}
assets/js/main.js
目前为空,用于未来添加自定义JavaScript功能。
// assets/js/main.js // 可以在这里添加一些交互逻辑
如何运行
- 安装环境:确保你的电脑上已经安装了PHP和MySQL,并且环境变量配置正确,推荐使用集成的开发环境如 XAMPP、WAMP 或 MAMP。
- 创建项目目录:在你的Web服务器根目录(XAMPP 的
htdocs文件夹)下创建一个名为wap-php-source的文件夹。 - 上传文件:将上述所有文件和文件夹结构完整地复制到
wap-php-source目录中。 - 配置数据库:打开
config/database.php文件,修改DB_NAME,DB_USER, 和DB_PASS为你自己的数据库信息。 - 导入数据库:使用你的MySQL客户端(如 phpMyAdmin)或命令行,将第4.1节的SQL代码导入到你创建的数据库中。
- 访问网站:启动你的Apache服务器,然后在浏览器中访问
http://localhost/wap-php-source/。
你应该能看到一个清爽的、适配手机的网站首页,点击文章链接可以查看详情。
扩展建议
这个源码是一个很好的起点,你可以基于它进行扩展:
- 用户系统:增加用户注册、登录、个人中心功能。
- 评论系统:在文章详情页下方增加评论框和评论列表。
- 后台管理:创建一个后台管理界面,用于发布、编辑和删除文章。
- 前端框架:可以使用 Vue.js 或 React 等现代前端框架来重构视图层,实现更丰富的交互体验。
- API化:将后端改造为RESTful API,为移动App或单页应用提供数据服务。
