文档
Slim 4 入门教程:Task API 服务
1. 背景
Slim 是构建轻量 API 的最佳 PHP 框架。本教程将构建完整的 Task CRUD API,掌握路由分组、中间件模式和 PSR-7 消息处理。
2. 前置概念
| 概念 | 说明 |
|---|---|
| PSR-7 Request/Response | HTTP 消息抽象 |
| PSR-15 Middleware | 请求-响应处理链 |
| Route Groups | 路由分组共享中间件 |
| Closure vs Class Handler | 闭包处理器 vs 类处理器 |
3. 分步操作
步骤一:项目初始化
mkdir task-api && cd task-api
composer require slim/slim:"4.*"
composer require slim/psr7
mkdir -p public src/Handlers
步骤二:数据库初始化
CREATE TABLE tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
description TEXT,
status TEXT DEFAULT 'pending',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
步骤三: 入口文件 public/index.php
<?php
require __DIR__ . '/../vendor/autoload.php';
use Slim\Factory\AppFactory;
$app = AppFactory::create();
$app->addErrorMiddleware(true, true, true);
// 加载路由
(require __DIR__ . '/../config/routes.php')($app);
$app->run();
步骤四:路由 config/routes.php
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\App;
return function (App $app) {
$pdo = new PDO('sqlite:../data/tasks.db');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$app->group('/api/tasks', function ($group) use ($pdo) {
$group->get('', function (Request $req, Response $res) use ($pdo): Response {
$stmt = $pdo->query('SELECT * FROM tasks ORDER BY id DESC');
$payload = json_encode($stmt->fetchAll(PDO::FETCH_ASSOC));
$res->getBody()->write($payload);
return $res->withHeader('Content-Type', 'application/json');
});
$group->post('', function (Request $req, Response $res) use ($pdo): Response {
$data = json_decode($req->getBody()->__toString(), true);
$stmt = $pdo->prepare('INSERT INTO tasks (title, description) VALUES (:title, :description)');
$stmt->execute([
':title' => $data['title'],
':description' => $data['description'] ?? '',
]);
$id = $pdo->lastInsertId();
$payload = json_encode(['id' => $id, 'message' => 'Task created']);
$res->getBody()->write($payload);
return $res->withHeader('Content-Type', 'application/json')->withStatus(201);
});
$group->put('/{id}', function (Request $req, Response $res, array $args) use ($pdo): Response {
$data = json_decode($req->getBody()->__toString(), true);
$stmt = $pdo->prepare('UPDATE tasks SET title = :title, status = :status, updated_at = CURRENT_TIMESTAMP WHERE id = :id');
$stmt->execute([
':title' => $data['title'] ?? '',
':status' => $data['status'] ?? 'pending',
':id' => $args['id'],
]);
$payload = json_encode(['message' => 'Task updated']);
$res->getBody()->write($payload);
return $res->withHeader('Content-Type', 'application/json');
});
$group->delete('/{id}', function (Request $req, Response $res, array $args) use ($pdo): Response {
$stmt = $pdo->prepare('DELETE FROM tasks WHERE id = :id');
$stmt->execute([':id' => $args['id']]);
return $res->withStatus(204);
});
});
};
4. 验证
php -S localhost:8080 -t public/
curl -X POST http://localhost:8080/api/tasks \
-H "Content-Type: application/json" \
-d '{"title":"Learn Slim 4"}'
curl http://localhost:8080/api/tasks
5. 思考题
- 如何将闭包路由重构为独立的 Action 类?
- 如何添加 JSON 校验中间件?
- 如何集成 Eloquent ORM 替代原生 PDO?