Skip to content

第2.4章:PlanetController API 控制器

学习时间: 1 小时


1. 控制器:宇宙对象管理中心

在 MVC 架构中,控制器是模型和请求之间的中介:

  • 📡 接收 HTTP 请求 (GET, POST, PUT, DELETE)
  • 🔍 通过模型从数据库中提取数据
  • 📦 格式化 API 的 JSON 响应

💡 宇宙类比: PlanetController = 任务控制中心:

  • 接收来自地球的请求(GET /planets
  • 向“探测器”(模型)发出指令
  • 以 JSON 格式返回遥测数据

2. 创建资源控制器

资源控制器自动包含用于 CRUD 操作的方法。

步骤 1:生成控制器

php artisan make:controller PlanetController --api --model=Planet

将在 app/Http/Controllers/PlanetController.php 中创建以下内容:

<?php

namespace App\Http\Controllers;

use App\Models\Planet;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule; // 别忘了添加此导入

class PlanetController extends Controller
{
    // 显示行星列表
    public function index(Request $request) {}

    // 创建新行星
    public function store(Request $request) {}

    // 显示特定行星
    public function show(Planet $planet) {}

    // 更新行星
    public function update(Request $request, Planet $planet) {}

    // 删除行星
    public function destroy(Planet $planet) {}
}


3. 实现 API 方法

A. index() - 获取行星列表

<?php
public function index(Request $request)
{
    // 获取分页行星,每页 15 个
    $planets = Planet::paginate($request->get('per_page', 15));
    return response()->json($planets); // 自动 200 OK
}

B. store() - 创建新行星

<?php
public function store(Request $request)
{
    $data = $request->validate([
        'name' => 'required|string|max:255|unique:planets',
        'description' => 'required|string',
        'size_km' => 'required|integer|min:100',
        'solar_system' => 'required|string|max:100',
        'image_url' => 'nullable|url',
        'is_habitable' => 'boolean'
    ]);

    $planet = Planet::create($data);
    return response()->json($planet, 201); // 201 Created
}

C. show() - 查看单个行星

<?php
public function show(Planet $planet)
{
    return response()->json($planet); // 自动 200 OK
}

D. update() - 更新行星

<?php
public function update(Request $request, Planet $planet)
{
    $data = $request->validate([
        'name' => [
            'string',
            'max:255',
            Rule::unique('planets')->ignore($planet->id),
        ],
        'description' => 'sometimes|string', // 'sometimes' - 仅当字段存在时才验证
        'size_km' => 'sometimes|integer|min:100',
        'solar_system' => 'sometimes|string|max:100',
        'image_url' => 'sometimes|nullable|url',
        'is_habitable' => 'sometimes|boolean'
    ]);

    $planet->update($data);
    return response()->json($planet); // 200 OK
}

E. destroy() - 删除行星

<?php
public function destroy(Planet $planet)
{
    $planet->delete();
    return response()->json(null, 204); // 204 No Content
}


4. 路由模型绑定 (Route Model Binding)

Laravel 根据 ID 自动注入行星对象:

// 在路由中: GET /planets/{planet}
// 在方法中: show(Planet $planet)

  • 如果行星未找到 → 自动 404
  • 无需手动调用 findOrFail() 查询

5. 响应格式化

index() 方法的改进响应示例:

<?php
public function index()
{
    return response()->json([
        'success' => true,
        'data' => Planet::all(),
        'message' => '行星获取成功'
    ]);
}

404 错误响应(自动):

{
    "message": "No query results for model [App\\Models\\Planet] 123",
    "exception": "Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException"
}


巩固测验

1. 用于创建 API 控制器的标志:

2. 成功创建时应返回什么状态?

3. 路由模型绑定允许:

4. 删除行星时返回:

5. $request->validate() 用于:


🚀 本章总结:

您已经创建了行星系统的“控制台”!现在您的控制器能够:

  • 🌌 显示行星列表(index
  • 🪐 创建新世界(store
  • 🔭 详细显示行星数据(show
  • 🛠️ 更新信息(update
  • 💥 销毁行星(destroy

剩下的就是配置路由了! 在下一章中,我们将把控制器连接到 API 路由。

📌 检查:

确保 app/Http/Controllers 中存在包含 5 个方法的 PlanetController.php 文件。

⚠️ 如果有错误:

  • 检查模型名称:use App\Models\Planet;
  • 检查导入
  • 对于 PostgreSQL:确保 Planet::all() 返回数据
  • 如果 Tinker 出现问题:执行 composer dump-autoload