您的当前位置:首页>全部文章>文章详情

【Webman+MySQL教程五】开发完整的 JSON 接口:统一返回、参数校验与异常处理

果子发表于:2026-10-04 14:11:56浏览:4次TAG: #webman #PHP #MySql #RESTful

本篇目标

把前 4 篇串起来,完成一个可用的学生管理 JSON API:统一返回格式、请求参数校验、全局异常处理,并用命令行验证全部接口。这是本系列的收官篇。

一、接口规划

方法路径说明
GET/api/student/list分页列表,支持 class_name 筛选
GET/api/student/detail详情(?id=1)
POST/api/student/add新增
POST/api/student/update修改
POST/api/student/delete删除

二、统一返回结构

先在 app/functions.php 里加两个 helper,全项目复用:

function success($data = [], string $msg = 'ok')
{
    return json(['code' => 0, 'msg' => $msg, 'data' => $data]);
}

function error(string $msg = 'fail', int $code = 1)
{
    return json(['code' => $code, 'msg' => $msg]);
}

三、控制器完整实现

app/controller/StudentController.php:

<?php
namespace app\controller;

use support\Request;
use app\model\Student;

class StudentController
{
    public function list(Request $request)
    {
        $page  = max(1, (int)$request->get('page', 1));
        $limit = min(50, max(1, (int)$request->get('limit', 10)));
        $class = $request->get('class_name');

        $query = Student::query();
        if ($class) {
            $query->where('class_name', $class);
        }
        $paginate = $query->orderBy('id', 'desc')->paginate($limit);

        return success([
            'total' => $paginate->total(),
            'page'  => $paginate->currentPage(),
            'items' => $paginate->items(),
        ]);
    }

    public function detail(Request $request)
    {
        $id = (int)$request->get('id');
        $stu = Student::find($id);
        return $stu ? success($stu) : error('记录不存在', 404);
    }

    public function add(Request $request)
    {
        $name  = trim((string)$request->post('name'));
        $class = trim((string)$request->post('class_name'));
        $score = (float)$request->post('score', 0);

        if ($name === '' || $class === '') {
            return error('name 和 class_name 必填');
        }
        if ($score < 0 || $score > 100) {
            return error('score 必须在 0-100 之间');
        }

        $stu = Student::create([
            'name' => $name, 'class_name' => $class, 'score' => $score,
        ]);
        return success(['id' => $stu->id], '新增成功');
    }

    public function update(Request $request)
    {
        $id = (int)$request->post('id');
        $stu = Student::find($id);
        if (!$stu) {
            return error('记录不存在', 404);
        }
        foreach (['name', 'class_name', 'score'] as $field) {
            $val = $request->post($field);
            if ($val !== null) {
                $stu->$field = $val;
            }
        }
        $stu->save();
        return success($stu, '更新成功');
    }

    public function delete(Request $request)
    {
        $id = (int)$request->post('id');
        $deleted = Student::where('id', $id)->delete();
        return $deleted ? success([], '删除成功') : error('记录不存在', 404);
    }
}

四、注册路由

config/route.php:

use support\\Router;
use app\\controller\\StudentController;

Route::group('/api/student', function () {
    Route::get('/list',   [StudentController::class, 'list']);
    Route::get('/detail', [StudentController::class, 'detail']);
    Route::post('/add',     [StudentController::class, 'add']);
    Route::post('/update',  [StudentController::class, 'update']);
    Route::post('/delete',  [StudentController::class, 'delete']);
});

五、全局异常兜底

接口最怕裸奔报错返回 HTML 堆栈。编辑 config/app.php 指定自定义异常处理:

'exception_handler' => app\exception\Handler::class,

app/exception/Handler.php:

<?php
namespace app\exception;

use Throwable;
use support\Request;

class Handler
{
    public function render(Request $request, Throwable $e)
    {
        // 开发环境可返回详细信息,生产环境只回固定话术并记日志
        debug_print_backtrace();
        return json([
            'code' => 500,
            'msg'  => '服务器开小差了:' . $e->getMessage(),
        ], 500);
    }
}

六、命令行验证

# 列表
curl "http://127.0.0.1:8787/api/student/list?page=1&limit=2"

# 新增
curl -X POST "http://127.0.0.1:8787/api/student/add" -d "name=周九&class_name=党校3班&score=85"

# 修改
curl -X POST "http://127.0.0.1:8787/api/student/update" -d "id=4&score=99"

# 删除
curl -X POST "http://127.0.0.1:8787/api/student/delete" -d "id=4"

全部返回 {"code":0,...} 即打通。

系列回顾

  1. 安装与 Hello World:常驻内存框架的基本盘。
  2. 路由与控制器:参数获取、响应、分组。
  3. 连接 MySQL:webman/database 配置与 gone away 问题。
  4. ORM 模型:Eloquent CRUD 与查询构建器。
  5. 完整 API:统一结构、校验、异常兜底。

下一步可以继续深入:中间件鉴权(webman-auth / JWT)、Redis 缓存(webman/redis)、连接池(webman/db)。祝编码愉快!