模核心理念
- 关注点分离:将 HTML 结构、CSS 样式、PHP 业务逻辑和 MySQL 数据访问分开,使代码更清晰、更易维护。
- 安全性:使用 预处理语句 来防止 SQL 注入攻击,这是 PHP 与 MySQL 交互的黄金标准。
- 可扩展性:基于 MVC(Model-View-Controller)的简化思想,方便您未来添加新功能(如博客、作品集等)。
- 简洁性:代码力求简单易懂,适合学习和二次开发。
项目结构
创建一个项目文件夹,并在其中建立以下目录和文件结构:

(图片来源网络,侵删)
/personal_website/
|-- assets/
| |-- css/
| | `-- style.css # 全局样式文件
| |-- js/
| | `-- script.js # 全局脚本文件
| `-- images/
| |-- profile.jpg # 你的头像
| `-- ... # 其他图片
|-- config/
| `-- database.php # 数据库连接配置
|-- includes/
| |-- header.php # 公共头部 (包含 <head> 和导航栏)
| |-- footer.php # 公共尾部 (包含页脚和闭合标签)
| `-- functions.php # 通用函数库
|-- index.php # 首页
|-- about.php # 关于我页面
|-- contact.php # 联系方式页面
|-- projects.php # 项目展示页面
|-- send_message.php # 处理联系表单提交的后台脚本
`-- README.md # 项目说明文件
数据库设计
我们需要一个简单的数据库来存储你的联系方式信息(以防泄露邮箱)和访客留言。
-
创建数据库: 在你的 MySQL 管理工具(如 phpMyAdmin)中执行以下 SQL 语句来创建数据库和表。
-- 创建数据库 CREATE DATABASE personal_website_db; -- 使用数据库 USE personal_website_db; -- 创建 messages 表,用于存储访客留言 CREATE TABLE messages ( id INT(11) AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, email VARCHAR(100) NOT NULL, subject VARCHAR(255) NOT NULL, message TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- (可选) 创建 projects 表,用于展示项目 CREATE TABLE projects ( id INT(11) AUTO_INCREMENT PRIMARY KEY, title VARCHAR(255) NOT NULL, description TEXT NOT NULL, image_url VARCHAR(255), project_url VARCHAR(255), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -
插入示例数据: 向
projects表中添加一些你的项目示例。INSERT INTO projects (title, description, image_url, project_url) VALUES ('个人项目一', '这是一个关于...的详细描述。', 'assets/images/project1.jpg', 'https://github.com/yourusername/project1'), ('个人项目二', '另一个有趣的项目,展示了...技术。', 'assets/images/project2.jpg', 'https://github.com/yourusername/project2');
核心文件代码
下面是各个关键文件的代码实现。

(图片来源网络,侵删)
config/database.php - 数据库连接
这个文件负责建立与 MySQL 数据库的连接。
<?php
// 防止直接访问此文件
if (!defined('ALLOW_ACCESS')) {
die('Direct access not permitted');
}
// 数据库配置
define('DB_HOST', 'localhost'); // 数据库主机
define('DB_USER', 'root'); // 数据库用户名
define('DB_PASS', ''); // 数据库密码
define('DB_NAME', 'personal_website_db'); // 数据库名
// 创建连接
$conn = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
// 检查连接是否成功
if ($conn->connect_error) {
// 在开发环境中,可以显示详细错误信息
die("数据库连接失败: " . $conn->connect_error);
// 在生产环境中,应该显示一个更友好的错误页面
// die("数据库连接错误,请稍后再试。");
}
// 设置字符集为 utf8mb4,以支持更广泛的字符(包括 emoji)
$conn->set_charset("utf8mb4");
?>
includes/header.php - 公共头部
<?php
// 确保在其他页面包含此文件时,已经定义了页面标题
$pageTitle = !empty($pageTitle) ? $pageTitle : '我的个人主页';
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"><?php echo $pageTitle; ?></title>
<link rel="stylesheet" href="assets/css/style.css">
<!-- 可以在这里添加 Font Awesome 或其他图标库 -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
</head>
<body>
<header>
<div class="container">
<a href="index.php" class="logo">我的名字</a>
<nav>
<ul>
<li><a href="index.php">首页</a></li>
<li><a href="about.php">关于我</a></li>
<li><a href="projects.php">项目</a></li>
<li><a href="contact.php">联系我</a></li>
</ul>
</nav>
</div>
</header>
<main class="container">
includes/footer.php - 公共尾部
</main> <!-- 关闭 main.container -->
<footer>
<div class="container">
<p>© <?php echo date('Y'); ?> 我的名字. All rights reserved.</p>
<div class="social-links">
<a href="https://github.com/yourusername" target="_blank"><i class="fab fa-github"></i></a>
<a href="https://linkedin.com/in/yourusername" target="_blank"><i class="fab fa-linkedin"></i></a>
<a href="https://twitter.com/yourusername" target="_blank"><i class="fab fa-twitter"></i></a>
</div>
</div>
</footer>
<script src="assets/js/script.js"></script>
</body>
</html>
includes/functions.php - 通用函数
<?php
// 引入数据库连接文件
require_once 'config/database.php';
/**
* 获取所有项目
* @return array 项目数组
*/
function getProjects() {
global $conn;
$projects = [];
$sql = "SELECT * FROM projects ORDER BY created_at DESC";
$result = $conn->query($sql);
if ($result && $result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$projects[] = $row;
}
}
return $projects;
}
/**
* 保存新留言
* @param string $name
* @param string $email
* @param string $subject
* @param string $message
* @return bool 是否成功
*/
function saveMessage($name, $email, $subject, $message) {
global $conn;
// 使用预处理语句防止 SQL 注入
$stmt = $conn->prepare("INSERT INTO messages (name, email, subject, message) VALUES (?, ?, ?, ?)");
if ($stmt === false) {
return false;
}
// "ssss" 表示四个参数都是字符串
$stmt->bind_param("ssss", $name, $email, $subject, $message);
$success = $stmt->execute();
$stmt->close();
return $success;
}
?>
页面文件示例
index.php - 首页
<?php
$pageTitle = '首页';
// 引入头部
require_once 'includes/header.php';
?>
<section class="hero">
<h1>你好,我是 <span class="highlight">你的名字</span></h1>
<p>一名热爱编程的全栈开发者 / 设计师 / 创作者</p>
<a href="about.php" class="btn">了解更多</a>
</section>
<section class="features">
<h2>我的技能</h2>
<div class="feature-grid">
<div class="feature-card">
<i class="fas fa-code"></i>
<h3>前端开发</h3>
<p>HTML, CSS, JavaScript, PHP</p>
</div>
<div class="feature-card">
<i class="fas fa-database"></i>
<h3>后端开发</h3>
<p>MySQL, API 设计, 服务器</p>
</div>
<div class="feature-card">
<i class="fas fa-paint-brush"></i>
<h3>UI/UX 设计</h3>
<p>Figma, Adobe XD, 用户体验</p>
</div>
</div>
</section>
<?php
// 引入尾部
require_once 'includes/footer.php';
?>
projects.php - 项目展示页
<?php
$pageTitle = '我的项目';
require_once 'includes/header.php';
require_once 'includes/functions.php';
?>
<h2>项目展示</h2>
<div class="projects-grid">
<?php
$projects = getProjects();
if (empty($projects)) {
echo '<p>暂无项目展示。</p>';
} else {
foreach ($projects as $project) {
echo '<div class="project-card">';
// 注意:确保图片路径正确
echo '<img src="' . htmlspecialchars($project['image_url']) . '" alt="' . htmlspecialchars($project['title']) . '">';
echo '<h3>' . htmlspecialchars($project['title']) . '</h3>';
echo '<p>' . htmlspecialchars($project['description']) . '</p>';
echo '<a href="' . htmlspecialchars($project['project_url']) . '" target="_blank" class="btn">查看项目</a>';
echo '</div>';
}
}
?>
</div>
<?php
require_once 'includes/footer.php';
?>
contact.php - 联系方式与留言表单
<?php
$pageTitle = '联系我';
require_once 'includes/header.php';
?>
<h2>联系我</h2>
<p>有项目想合作?或者只是想打个招呼?欢迎通过下面的表单留言给我。</p>
<div class="contact-container">
<div class="contact-info">
<h3>其他联系方式</h3>
<p><i class="fas fa-envelope"></i> your.email@example.com</p>
<p><i class="fas fa-phone"></i> +86 123 4567 8900</p>
<p><i class="fas fa-map-marker-alt"></i> 中国, 北京</p>
</div>
<div class="contact-form">
<h3>发送留言</h3>
<?php
// 检查是否刚刚提交了表单并显示成功消息
if (isset($_GET['status']) && $_GET['status'] == 'success') {
echo '<div class="alert success">留言发送成功!我会尽快回复您。</div>';
}
?>
<form action="send_message.php" method="POST">
<div class="form-group">
<label for="name">姓名</label>
<input type="text" id="name" name="name" required>
</div>
<div class="form-group">
<label for="email">邮箱</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="subject">主题</label>
<input type="text" id="subject" name="subject" required>
</div>
<div class="form-group">
<label for="message">留言内容</label>
<textarea id="message" name="message" rows="5" required></textarea>
</div>
<button type="submit" class="btn">发送留言</button>
</form>
</div>
</div>
<?php
require_once 'includes/footer.php';
?>
send_message.php - 处理留言提交
这个文件是后台脚本,用户看不到它的内容。
<?php
// 1. 引入函数文件
require_once 'includes/functions.php';
// 2. 检查是否是 POST 请求
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// 3. 获取并清理表单数据
$name = trim($_POST['name']);
$email = trim($_POST['email']);
$subject = trim($_POST['subject']);
$message = trim($_POST['message']);
// 4. 简单的验证
if (empty($name) || empty($email) || empty($subject) || empty($message)) {
// 可以在这里添加更详细的错误处理,并重定向回表单页面并显示错误
header("Location: contact.php?error=empty_fields");
exit();
}
// 5. 调用函数保存数据
if (saveMessage($name, $email, $subject, $message)) {
// 成功,重定向到联系页并显示成功消息
header("Location: contact.php?status=success");
} else {
// 失败,重定向并显示错误消息
header("Location: contact.php?status=error");
}
} else {
// 如果不是 POST 请求,重定向到首页
header("Location: index.php");
}
exit();
?>
CSS 和 JS (简略版)
assets/css/style.css
/* 全局样式 */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Arial', sans-serif;
line-height: 1.6;
background-color: #f4f4f4;
color: #333;
}
.container {
width: 80%;
max-width: 1100px;
margin: auto;
overflow: hidden;
padding: 0 2rem;
}
/* 头部导航 */
header {
background: #333;
color: #fff;
padding: 1rem 0;
position: sticky;
top: 0;
z-index: 1000;
}
header .container {
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
color: #fff;
text-decoration: none;
font-size: 1.5rem;
font-weight: bold;
}
nav ul {
display: flex;
list-style: none;
}
nav ul li a {
color: #fff;
text-decoration: none;
padding: 0.5rem 1rem;
transition: background 0.3s;
}
nav ul li a:hover {
background: #555;
}
区 */
main {
padding: 2rem 0;
}
/* 首页英雄区 */
.hero {
text-align: center;
padding: 4rem 0;
background: linear-gradient(rgba(0,0,0,0.7), rgba(0,0,0,0.7)), url('https://source.unsplash.com/random/1600x900?tech,code') no-repeat center center/cover;
color: #fff;
margin-bottom: 2rem;
}
.hero h1 { font-size: 3rem; }
.highlight { color: #00d2ff; }
.btn {
display: inline-block;
background: #00d2ff;
color: #333;
padding: 0.8rem 1.5rem;
margin-top: 1rem;
text-decoration: none;
border-radius: 5px;
font-weight: bold;
transition: background 0.3s;
}
.btn:hover { background: #00a8cc; }
/* 项目和特性网格 */
.projects-grid, .feature-grid, .contact-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
.project-card, .feature-card {
background: #fff;
border: 1px solid #ddd;
border-radius: 5px;
padding: 1.5rem;
text-align: center;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.project-card img { max-width: 100%; height: auto; margin-bottom: 1rem; border-radius: 5px; }
/* 联系表单 */
.contact-container { display: flex; gap: 2rem; }
.contact-info, .contact-form { flex: 1; background: #fff; padding: 2rem; border-radius: 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
.form-group { margin-bottom: 1rem; }
.form-group label { display: block; margin-bottom: 0.5rem; }
.form-group input, .form-group textarea { width: 100%; padding: 0.8rem; border: 1px solid #ddd; border-radius: 5px; }
/* 页脚 */
footer {
background: #333;
color: #fff;
text-align: center;
padding: 1rem 0;
margin-top: 2rem;
}
.social-links a { color: #fff; margin: 0 0.5rem; font-size: 1.2rem; }
/* 响应式设计 */
@media (max-width: 768px) {
header .container { flex-direction: column; }
nav ul { margin-top: 1rem; }
.hero h1 { font-size: 2rem; }
.contact-container { flex-direction: column; }
}
/* 提示消息 */
.alert {
padding: 1rem;
margin-bottom: 1rem;
border-radius: 5px;
}
.success { background-color: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
.error { background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }
assets/js/script.js (目前可以为空,但保留以备将来使用)
// document.addEventListener('DOMContentLoaded', function() {
// // 在这里放置需要在页面加载完成后执行的 JavaScript 代码
// });
如何使用和部署
- 本地环境:你需要一个本地服务器环境,如 XAMPP、WAMP 或 MAMP,将整个
personal_website文件夹放入服务器的根目录(如 XAMPP 的htdocs)。 - 配置数据库:根据你的本地环境,修改
config/database.php中的DB_USER和DB_PASS(默认通常是root和空密码)。 - 创建数据库和表:按照第二部分的 SQL 语句,在 phpMyAdmin 中创建数据库和表。
- 访问网站:启动你的本地服务器,然后在浏览器中访问
http://localhost/personal_website/。 - 部署到线上:购买虚拟主机和域名后,通过 FTP 或文件管理器将所有文件上传到主机,同样,你需要在线上数据库中创建相同的表,并修改
config/database.php中的数据库连接信息为你的线上主机信息。
这个模板为你提供了一个坚实的基础,你可以根据它来打造完全属于你自己的个人网站,祝你成功!
