Laravel 框架核心:Service 层封装,让代码更优雅

分类:后端开发 时间:2026-02-24 浏览:1
1

一、为什么需要 Service 层?

Laravel 默认的 MVC 架构中,Controller 容易 “臃肿”:

  • 一个接口的逻辑(参数验证、业务处理、数据入库、异常处理)全部写在 Controller,代码行数超百行;

  • 相同业务逻辑(如用户注册、订单创建)在多个 Controller 重复编写,维护成本高;

  • Controller 既处理请求响应,又处理业务逻辑,违反 “单一职责原则”。

解决方案:引入 Service 层,分层职责:

  • Controller:仅接收请求、调用 Service、返回响应;

  • Service:封装核心业务逻辑;

  • Model:仅处理数据交互(查询、入库、关联)。

二、Service 层实战:用户注册功能

1. 创建 Service 类

app/Services目录下创建UserService.php(无该目录则手动创建):

<?php
namespace App\Services;

use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;

class UserService
{
    /**
     * 用户注册
     * @param array $data 注册数据(username/email/password)
     * @return User
     * @throws ValidationException
     */
    public function register(array $data): User
    {
        // 1. 参数验证
        $this->validateRegisterData($data);

        // 2. 检查邮箱是否已存在
        if (User::where('email', $data['email'])->exists()) {
            throw ValidationException::withMessages([
                'email' => '该邮箱已被注册'
            ]);
        }

        // 3. 密码加密
        $data['password'] = Hash::make($data['password']);

        // 4. 数据入库
        $user = User::create([
            'username' => $data['username'],
            'email' => $data['email'],
            'password' => $data['password']
        ]);

        // 5. 额外业务逻辑(如发送注册成功邮件)
        $this->sendRegisterEmail($user);

        return $user;
    }

    /**
     * 验证注册数据
     * @param array $data
     * @throws ValidationException
     */
    private function validateRegisterData(array $data): void
    {
        $rules = [
            'username' => 'required|string|min:3|max:20',
            'email' => 'required|email|max:100',
            'password' => 'required|string|min:6|confirmed'
        ];

        $validator = \Illuminate\Support\Facades\Validator::make($data, $rules);
        if ($validator->fails()) {
            throw new ValidationException($validator);
        }
    }

    /**
     * 发送注册成功邮件
     * @param User $user
     */
    private function sendRegisterEmail(User $user): void
    {
        // 此处可集成邮件发送逻辑,示例仅做占位
        \Illuminate\Support\Facades\Mail::raw("恭喜{$user->username}注册成功!", function ($message) use ($user) {
            $message->to($user->email)->subject('注册成功');
        });
    }
}
?>
2. Controller 调用 Service

修改app/Http/Controllers/Auth/RegisterController.php

<?php
namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Services\UserService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;

class RegisterController extends Controller
{
    protected $userService;

    // 依赖注入:Laravel自动实例化UserService
    public function __construct(UserService $userService)
    {
        $this->userService = $userService;
    }

    /**
     * 处理用户注册请求
     * @param Request $request
     * @return JsonResponse
     */
    public function register(Request $request): JsonResponse
    {
        try {
            // 调用Service处理注册逻辑
            $user = $this->userService->register($request->all());

            return response()->json([
                'code' => 200,
                'message' => '注册成功',
                'data' => [
                    'id' => $user->id,
                    'username' => $user->username,
                    'email' => $user->email
                ]
            ]);
        } catch (ValidationException $e) {
            return response()->json([
                'code' => 400,
                'message' => '参数错误',
                'errors' => $e->errors()
            ], 400);
        } catch (\Exception $e) {
            return response()->json([
                'code' => 500,
                'message' => '服务器错误:' . $e->getMessage()
            ], 500);
        }
    }
}
?>
3. 路由配置

routes/api.php中添加路由:

Route::post('/register', [\App\Http\Controllers\Auth\RegisterController::class, 'register']);

三、Service 层进阶技巧

  1. 事务处理:涉及多表操作时,在 Service 中开启事务:

use Illuminate\Support\Facades\DB;

public function createOrder(array $data)
{
    // 开启事务
    return DB::transaction(function () use ($data) {
        // 创建订单
        $order = Order::create($data);
        // 扣减商品库存
        $this->reduceStock($data['goods_id'], $data['num']);
        // 记录订单日志
        OrderLog::create(['order_id' => $order->id, 'content' => '订单创建']);
        return $order;
    });
}
  1. 异常统一捕获:创建自定义异常类(如BusinessException),在 Service 中抛出,在app/Exceptions/Handler.php中统一处理,避免 Controller 中重复写 try-catch。

  2. Service 复用:多个 Controller 可调用同一个 Service 方法,如UserServicegetUserInfo()可在个人中心、订单详情等接口中复用。

文章链接:http://www.qwkf.cn//houduan/23.html
文章标题:Laravel 框架核心:Service 层封装,让代码更优雅

相关阅读