PHP 怎么PHP 看板

wen PHP项目 2

本文目录导读:

PHP 怎么PHP 看板

  1. PHP看板创建方式
  2. 推荐工具和库
  3. 简单实现例子

我来帮您解答如何在PHP中创建看板(Kanban Board)。

PHP看板创建方式

纯PHP后端 + 前端HTML/CSS/JavaScript

<?php
// task_board.php
class KanbanBoard {
    private $tasks = [
        'todo' => [],
        'in_progress' => [],
        'done' => []
    ];
    public function addTask($column, $task) {
        if (isset($this->tasks[$column])) {
            $this->tasks[$column][] = $task;
        }
    }
    public function moveTask($from, $to, $taskIndex) {
        if (isset($this->tasks[$from][$taskIndex])) {
            $task = $this->tasks[$from][$taskIndex];
            unset($this->tasks[$from][$taskIndex]);
            $this->tasks[$to][] = $task;
        }
    }
    public function getBoard() {
        return $this->tasks;
    }
}
$board = new KanbanBoard();
$board->addTask('todo', '开发登录功能');
$board->addTask('todo', '设计数据库');
$board->addTask('in_progress', '编写API文档');
?>

使用PHP框架+Laravel

// 使用Laravel框架
// web.php 路由
Route::get('/kanban', [KanbanController::class, 'index']);
Route::post('/kanban/task', [KanbanController::class, 'store']);
Route::put('/kanban/task/{id}/move', [KanbanController::class, 'move']);
// KanbanController.php
class KanbanController extends Controller {
    public function index() {
        $tasks = Task::all()->groupBy('status');
        return view('kanban.index', compact('tasks'));
    }
    public function store(Request $request) {
        $task = Task::create([
            'title' => $request->title,
            'status' => 'todo',
            'order' => Task::where('status', 'todo')->count() + 1
        ]);
        return response()->json($task);
    }
}

完整的前后端示例

<!-- kanban.html -->
<!DOCTYPE html>
<html>
<head>PHP Kanban Board</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css">
    <style>
        .kanban-column {
            min-height: 400px;
            background: #f4f5f7;
            border-radius: 3px;
            padding: 10px;
        }
        .task-card {
            background: white;
            padding: 10px;
            margin: 5px 0;
            border-radius: 3px;
            cursor: pointer;
            box-shadow: 0 1px 0 rgba(9,30,66,.25);
        }
    </style>
</head>
<body>
    <div class="container mt-5">
        <h2>PHP Kanban Board</h2>
        <div class="row">
            <div class="col-md-4">
                <div class="kanban-column" data-column="todo">
                    <h5>待办 (Todo)</h5>
                    <div id="todo-tasks">
                        <?php foreach($board['todo'] as $task): ?>
                            <div class="task-card" draggable="true">
                                <?php echo $task; ?>
                            </div>
                        <?php endforeach; ?>
                    </div>
                </div>
            </div>
            <div class="col-md-4">
                <div class="kanban-column" data-column="in_progress">
                    <h5>进行中 (In Progress)</h5>
                    <div id="in_progress-tasks">
                        <?php foreach($board['in_progress'] as $task): ?>
                            <div class="task-card" draggable="true">
                                <?php echo $task; ?>
                            </div>
                        <?php endforeach; ?>
                    </div>
                </div>
            </div>
            <div class="col-md-4">
                <div class="kanban-column" data-column="done">
                    <h5>已完成 (Done)</h5>
                    <div id="done-tasks">
                        <?php foreach($board['done'] as $task): ?>
                            <div class="task-card" draggable="true">
                                <?php echo $task; ?>
                            </div>
                        <?php endforeach; ?>
                    </div>
                </div>
            </div>
        </div>
        <div class="mt-3">
            <input type="text" id="new-task" placeholder="输入新任务" class="form-control w-25 d-inline">
            <button onclick="addTask()" class="btn btn-primary">添加任务</button>
        </div>
    </div>
    <script>
        // 拖拽功能
        document.addEventListener('dragstart', function(e) {
            if (e.target.classList.contains('task-card')) {
                e.dataTransfer.setData('text/plain', e.target.textContent);
                e.dataTransfer.setData('source-column', e.target.parentElement.id);
            }
        });
        document.querySelectorAll('.kanban-column').forEach(column => {
            column.addEventListener('dragover', function(e) {
                e.preventDefault();
            });
            column.addEventListener('drop', function(e) {
                e.preventDefault();
                const taskText = e.dataTransfer.getData('text/plain');
                const sourceColumn = e.dataTransfer.getData('source-column');
                const targetColumn = this.dataset.column;
                // PHP Ajax请求更新任务状态
                updateTaskStatus(taskText, sourceColumn, targetColumn);
                const taskElement = document.createElement('div');
                taskElement.className = 'task-card';
                taskElement.draggable = true;
                taskElement.textContent = taskText;
                this.querySelector('div').appendChild(taskElement);
            });
        });
        function addTask() {
            const task = document.getElementById('new-task').value;
            if (task.trim() !== '') {
                // 发送Ajax请求到PHP后端保存任务
                fetch('save_task.php', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                    },
                    body: 'task=' + encodeURIComponent(task) + '&column=todo'
                })
                .then(response => response.text())
                .then(data => {
                    const taskElement = document.createElement('div');
                    taskElement.className = 'task-card';
                    taskElement.draggable = true;
                    taskElement.textContent = task;
                    document.getElementById('todo-tasks').appendChild(taskElement);
                    document.getElementById('new-task').value = '';
                });
            }
        }
        function updateTaskStatus(task, from, to) {
            fetch('update_task.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: 'task=' + encodeURIComponent(task) + 
                     '&from=' + from + 
                     '&to=' + to
            });
        }
    </script>
</body>
</html>

PHP后端API示例

<?php
// save_task.php
header('Content-Type: application/json');
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $task = $_POST['task'] ?? '';
    $column = $_POST['column'] ?? 'todo';
    // 存储到数据库
    $db = new PDO('mysql:host=localhost;dbname=kanban', 'root', '');
    $stmt = $db->prepare("INSERT INTO tasks (title, status) VALUES (?, ?)");
    $stmt->execute([$task, $column]);
    echo json_encode(['success' => true, 'id' => $db->lastInsertId()]);
}
?>

数据库表结构

CREATE TABLE tasks (
    id INT AUTO_INCREMENT PRIMARY KEY,VARCHAR(255) NOT NULL,
    status ENUM('todo', 'in_progress', 'done') DEFAULT 'todo',
    priority INT DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

推荐工具和库

  1. Packagist包: jorelanbo/kanban - PHP看板库
  2. 前端库: SortableJS + PHP后端
  3. 全栈方案: Laravel + Vue.js + Dragula

简单实现例子

// 最简单的看板存储方式
$tasks = [
    'todo' => ['任务1', '任务2'],
    'in_progress' => ['任务3'],
    'done' => ['任务4']
];
// 保存到文件
file_put_contents('tasks.json', json_encode($tasks));
// 读取
$tasks = json_decode(file_get_contents('tasks.json'), true);

需要具体的哪一种实现方式,我可以提供更详细的代码示例。

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