如何用PHP项目实现日程管理?

wen java案例 1

本文目录导读:

如何用PHP项目实现日程管理?

  1. 数据库设计(MySQL)
  2. PHP核心代码结构
  3. 前端示例(使用JavaScript和FullCalendar)
  4. 主要功能特性
  5. 部署建议

我将为您介绍如何使用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>

主要功能特性

  1. 用户认证:基本用户登录/注册系统
  2. CRUD操作:创建、读取、更新、删除日程事件
  3. 日历视图:月视图、周视图、日视图
  4. 事件详情、描述、时间、地点、颜色
  5. 状态管理:待办、已完成、已取消
  6. 搜索和过滤:按日期、关键词搜索

部署建议

  1. 安全性

    • 使用预处理语句防止SQL注入
    • 实现CSRF保护
    • 对用户输入进行验证和清理
  2. 性能优化

    • 添加数据库索引
    • 实现缓存机制
    • 使用CDN加载前端库
  3. 扩展功能

    • 事件提醒(邮件/短信)
    • 重复事件(每日/每周/每月)
    • 事件分享和协作
    • 文件附件
    • 时间线视图

这个框架提供了一个完整的日程管理解决方案,您可以根据需要进一步定制和扩展。

抱歉,评论功能暂时关闭!