本文目录导读:

在 Laravel 中定义仓库接口(Repository Interface)的最佳实践如下:
创建接口文件
// app/Repositories/Contracts/UserRepositoryInterface.php
<?php
namespace App\Repositories\Contracts;
use App\Models\User;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
interface UserRepositoryInterface
{
/**
* 获取所有用户
*/
public function all(): Collection;
/**
* 分页获取用户
*/
public function paginate(int $perPage = 15): LengthAwarePaginator;
/**
* 根据ID查找用户
*/
public function find(int $id): ?User;
/**
* 创建用户
*/
public function create(array $data): User;
/**
* 更新用户
*/
public function update(int $id, array $data): User;
/**
* 删除用户
*/
public function delete(int $id): bool;
/**
* 根据条件查找用户
*/
public function findBy(string $field, mixed $value): ?User;
/**
* 获取活跃用户
*/
public function getActiveUsers(): Collection;
}
基础仓库接口(可选)
// app/Repositories/Contracts/BaseRepositoryInterface.php
<?php
namespace App\Repositories\Contracts;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
interface BaseRepositoryInterface
{
public function all(): Collection;
public function paginate(int $perPage = 15): LengthAwarePaginator;
public function find(int $id);
public function create(array $data);
public function update(int $id, array $data);
public function delete(int $id): bool;
public function findBy(string $field, mixed $value);
public function findAllBy(string $field, mixed $value): Collection;
public function findByMultiple(array $conditions): Collection;
}
带具体业务逻辑的接口
// app/Repositories/Contracts/OrderRepositoryInterface.php
<?php
namespace App\Repositories\Contracts;
use App\Models\Order;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
interface OrderRepositoryInterface
{
// 基础CRUD
public function all(): Collection;
public function paginate(int $perPage = 15): LengthAwarePaginator;
public function find(int $id): ?Order;
public function create(array $data): Order;
public function update(int $id, array $data): Order;
public function delete(int $id): bool;
// 特定业务方法
public function getOrdersByStatus(string $status): Collection;
public function getOrdersByDateRange(string $startDate, string $endDate): Collection;
public function getTotalRevenueByDateRange(string $startDate, string $endDate): float;
public function cancelOrder(int $id): bool;
public function processOrder(int $id): Order;
}
接口实现类
// app/Repositories/UserRepository.php
<?php
namespace App\Repositories;
use App\Models\User;
use App\Repositories\Contracts\UserRepositoryInterface;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
class UserRepository implements UserRepositoryInterface
{
public function __construct(
protected User $model
) {}
public function all(): Collection
{
return $this->model->all();
}
public function paginate(int $perPage = 15): LengthAwarePaginator
{
return $this->model->paginate($perPage);
}
public function find(int $id): ?User
{
return $this->model->find($id);
}
public function create(array $data): User
{
return $this->model->create($data);
}
public function update(int $id, array $data): User
{
$user = $this->find($id);
$user->update($data);
return $user;
}
public function delete(int $id): bool
{
return $this->model->destroy($id);
}
public function findBy(string $field, mixed $value): ?User
{
return $this->model->where($field, $value)->first();
}
public function getActiveUsers(): Collection
{
return $this->model->where('status', 'active')->get();
}
}
绑定接口到实现
// app/Providers/RepositoryServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Repositories\Contracts\UserRepositoryInterface;
use App\Repositories\UserRepository;
use App\Repositories\Contracts\OrderRepositoryInterface;
use App\Repositories\OrderRepository;
class RepositoryServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->bind(
UserRepositoryInterface::class,
UserRepository::class
);
$this->app->bind(
OrderRepositoryInterface::class,
OrderRepository::class
);
}
public function boot(): void
{
//
}
}
在 config/app.php 注册服务提供者
'providers' => [
// 其他服务提供者...
App\Providers\RepositoryServiceProvider::class,
],
在控制器中使用
// app/Http/Controllers/UserController.php
<?php
namespace App\Http\Controllers;
use App\Repositories\Contracts\UserRepositoryInterface;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function __construct(
protected UserRepositoryInterface $userRepository
) {}
public function index()
{
$users = $this->userRepository->paginate(10);
return view('users.index', compact('users'));
}
public function show(int $id)
{
$user = $this->userRepository->find($id);
return view('users.show', compact('user'));
}
public function store(Request $request)
{
$data = $request->validate([
'name' => 'required|string',
'email' => 'required|email|unique:users',
'password' => 'required|min:8',
]);
$user = $this->userRepository->create($data);
return redirect()->route('users.show', $user->id);
}
}
最佳实践建议
// 使用依赖注入自动绑定
// 不需要手动绑定,Laravel 会自动解析
// 可以将接口放在单独的文件中
// app/Contracts/Repositories/UserRepositoryInterface.php
// 使用 PHP 8 的属性自动解析
class UserController extends Controller
{
public function __construct(
private UserRepositoryInterface $userRepository
) {}
// 方法...
}
// 添加缓存支持
interface UserRepositoryInterface
{
public function findWithCache(int $id): ?User;
public function clearCache(): void;
}
使用 Artisan 命令生成
# 创建接口 php artisan make:interface UserRepositoryInterface --contract # 创建实现类 php artisan make:repository UserRepository --model=User # 创建服务提供者 php artisan make:provider RepositoryServiceProvider
通过定义接口,你可以:
- 实现依赖反转原则
- 方便单元测试(可以轻松 mock)
- 提高代码的可维护性
- 支持多数据源切换