如何在 Laravel 中为多种资源构建通用 CRUD 控制器

当前位置: 剧情吧 > php教程>
电视猫时间: 2025-01-08 10:42:08

  如何在 Laravel 中为多种资源构建通用 CRUD 控制器

在 Laravel 中,为多种资源构建通用的 CRUD 控制器可以通过以下方法实现,这不仅能减少代码重复,还能提高代码的可维护性。


目标

创建一个通用的 CRUD 控制器,支持多个资源(如 Post, User, Product 等),并确保易于扩展和维护。


方法 1: 使用单个通用控制器

步骤

1. 创建通用控制器

在命令行中运行以下命令:

php artisan make:controller GenericController

编辑 GenericController,实现基本 CRUD 功能:

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class GenericController extends Controller
{
    protected $model; // 动态绑定模型

    public function index()
    {
        // 获取所有资源
        return response()->json($this->model::all());
    }

    public function show($id)
    {
        // 获取单个资源
        $item = $this->model::findOrFail($id);
        return response()->json($item);
    }

    public function store(Request $request)
    {
        // 验证并创建资源
        $validatedData = $request->validate($this->model::validationRules());
        $item = $this->model::create($validatedData);
        return response()->json($item, 201);
    }

    public function update(Request $request, $id)
    {
        // 验证并更新资源
        $item = $this->model::findOrFail($id);
        $validatedData = $request->validate($this->model::validationRules());
        $item->update($validatedData);
        return response()->json($item);
    }

    public function destroy($id)
    {
        // 删除资源
        $item = $this->model::findOrFail($id);
        $item->delete();
        return response()->json(['message' => 'Deleted successfully'], 204);
    }
}

2. 为每种资源创建动态绑定的子控制器

假设我们有一个 Post 模型和一个 Product 模型。

运行命令生成资源模型:

php artisan make:model Post -m
php artisan make:model Product -m

创建 PostControllerProductController 并继承 GenericController

namespace App\Http\Controllers;

use App\Models\Post;

class PostController extends GenericController
{
    public function __construct()
    {
        $this->model = Post::class;
    }
}
namespace App\Http\Controllers;

use App\Models\Product;

class ProductController extends GenericController
{
    public function __construct()
    {
        $this->model = Product::class;
    }
}

3. 为模型添加验证规则

PostProduct 模型中添加静态方法 validationRules

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $fillable = ['title', 'content'];

    public static function validationRules()
    {
        return [
            'title' => 'required|string|max:255',
            'content' => 'required|string',
        ];
    }
}
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    use HasFactory;

    protected $fillable = ['name', 'price', 'description'];

    public static function validationRules()
    {
        return [
            'name' => 'required|string|max:255',
            'price' => 'required|numeric|min:0',
            'description' => 'nullable|string',
        ];
    }
}

4. 定义路由

routes/api.php 中为每个资源注册路由:

use App\Http\Controllers\PostController;
use App\Http\Controllers\ProductController;

Route::apiResource('posts', PostController::class);
Route::apiResource('products', ProductController::class);

方法 2: 使用 Laravel 的资源控制器基类

Laravel 提供了一个基础的 Controller,可以通过继承和自定义来实现通用功能。

步骤

1. 创建基础资源控制器

运行以下命令生成控制器:

php artisan make:controller BaseResourceController

编辑 BaseResourceController

namespace App\Http\Controllers;

use Illuminate\Http\Request;

abstract class BaseResourceController extends Controller
{
    abstract protected function model();

    public function index()
    {
        return response()->json($this->model()::all());
    }

    public function show($id)
    {
        return response()->json($this->model()::findOrFail($id));
    }

    public function store(Request $request)
    {
        $validatedData = $request->validate($this->model()::validationRules());
        return response()->json($this->model()::create($validatedData), 201);
    }

    public function update(Request $request, $id)
    {
        $item = $this->model()::findOrFail($id);
        $validatedData = $request->validate($this->model()::validationRules());
        $item->update($validatedData);
        return response()->json($item);
    }

    public function destroy($id)
    {
        $item = $this->model()::findOrFail($id);
        $item->delete();
        return response()->json(['message' => 'Deleted successfully'], 204);
    }
}

2. 为每种资源创建控制器并继承基础控制器

例如,创建 PostControllerProductController

namespace App\Http\Controllers;

use App\Models\Post;

class PostController extends BaseResourceController
{
    protected function model()
    {
        return Post::class;
    }
}
namespace App\Http\Controllers;

use App\Models\Product;

class ProductController extends BaseResourceController
{
    protected function model()
    {
        return Product::class;
    }
}

总结

两种方法都可以实现通用 CRUD 控制器:

  • 方法 1 通过动态绑定模型灵活实现,适合需要轻量化控制器的场景。
  • 方法 2 通过抽象基类提供强类型支持,适合更复杂的项目。

选择哪种方法取决于项目的复杂性和开发团队的偏好。

    最新电视剧
    热门电视剧
    影视资讯
    最新剧情排行榜
    最新电视剧剧情