repository接口应定义在app/contracts下,实现类放app/repositories;命名统一为xxxrepositoryinterface,实现类加eloquent前缀;需通过容器绑定并依赖注入,严禁硬编码new,且不得包含业务逻辑或http上下文。

Repository接口该定义在哪儿?
Laravel本身不强制Repository位置,但放在app/Repositories下最稳妥。别塞进app/Models——模型只管数据结构和基础CRUD,Repository才是封装查询逻辑的地方。如果项目已有app/Contracts,接口(如PostRepositoryInterface)建议放这儿;实现类EloquentPostRepository则放app/Repositories。路径错乱会导致Class not found或IDE无法跳转。
- 接口命名统一用
XXXRepositoryInterface,避免Repository后缀重复(比如别叫PostRepositoryRepository)
- 实现类名对应加
Eloquent前缀,明确技术栈,方便后续替换为Redis或API实现
- 别在Repository里调用
request()或session()——它只接受参数,不感知HTTP上下文
怎么让Repository真正解耦?关键在依赖注入方式
硬编码new EloquentPostRepository等于白写。必须通过Laravel容器绑定接口与实现,并在Controller构造函数中类型提示接口:
// 在AppServiceProvider@register()中
$this->app->bind(
PostRepositoryInterface::class,
EloquentPostRepository::class
);
- Controller里只写
public function __construct(PostRepositoryInterface $posts),绝不出现new或app()调用
- 如果某Repository需要传参(比如租户ID),不要在构造函数里硬塞,改用方法参数或setter注入
- 别为了“解耦”把简单查询也塞进Repository——单表
find()、all()直接用模型更清晰;Repository适合封装多表联查、复杂条件组合、缓存策略等
常见错误:Repository里写了业务逻辑
Repository的职责是「如何获取数据」,不是「数据拿来干嘛」。下面这些都越界了:
在getPublishedPosts()里调用Notification::send()
把订单创建+库存扣减+日志记录全塞进OrderRepository::createWithStockCheck()
返回数组而非Eloquent Collection或Model实例,导致后续无法链式调用->load()
业务规则(如“用户积分不足不能下单”)应放在Service层,Repository只负责提供user()->points和stock()->available
Laravel 13.2.0
PHP中文网提供Laravel 13.2.0版本下载,Laravel框架 是基于 PHP 8.3+ 的高性能框架,官方推荐通过 Composer 安装。它内置 AI SDK、JSON:API Resources 及原生向量搜索,支持属性驱动开发与队列路由,大幅提升开发效率。相比旧版,13.2.0 优化了缓存 TTL 管理与实时通信,无需 Redis 即可横向扩展。作为现代 Web 开发首选,它兼顾安全与极速体验,助您快速构建企业级应用。
下载
Repository方法命名聚焦数据动作:findBySlug()、withAuthorAndTags()、searchByKeywords(),不出现process、handle、validate这类词
返回值保持一致:要么全是Model/Collection,要么全是DTO(需显式转换),别混用
测试时Repository总报错找不到模型?
最常见的原因是模型没用use App\Models\Post;,而是用了use Illuminate\Database\Eloquent\Model;。Eloquent Repository里所有Post::query()调用都依赖具体模型类。
- 检查实现类里的
use语句,确保指向App\Models\XXX
- 测试时若用
RefreshDatabase,记得在Repository测试方法里手动Artisan::call('migrate')或使用内存SQLite(DB_CONNECTION=sqlite + database_path(':memory:'))
- 别在Repository里用
DB::table()绕过模型——这会让软删除、时间戳、访问器全部失效,也破坏了Eloquent抽象层
XXXRepositoryInterface,避免Repository后缀重复(比如别叫PostRepositoryRepository)Eloquent前缀,明确技术栈,方便后续替换为Redis或API实现request()或session()——它只接受参数,不感知HTTP上下文new EloquentPostRepository等于白写。必须通过Laravel容器绑定接口与实现,并在Controller构造函数中类型提示接口:
// 在AppServiceProvider@register()中
$this->app->bind(
PostRepositoryInterface::class,
EloquentPostRepository::class
);
- Controller里只写
public function __construct(PostRepositoryInterface $posts),绝不出现new或app()调用 - 如果某Repository需要传参(比如租户ID),不要在构造函数里硬塞,改用方法参数或setter注入
- 别为了“解耦”把简单查询也塞进Repository——单表
find()、all()直接用模型更清晰;Repository适合封装多表联查、复杂条件组合、缓存策略等
常见错误:Repository里写了业务逻辑
Repository的职责是「如何获取数据」,不是「数据拿来干嘛」。下面这些都越界了:
在getPublishedPosts()里调用Notification::send()
把订单创建+库存扣减+日志记录全塞进OrderRepository::createWithStockCheck()
返回数组而非Eloquent Collection或Model实例,导致后续无法链式调用->load()
业务规则(如“用户积分不足不能下单”)应放在Service层,Repository只负责提供user()->points和stock()->available
Laravel 13.2.0
PHP中文网提供Laravel 13.2.0版本下载,Laravel框架 是基于 PHP 8.3+ 的高性能框架,官方推荐通过 Composer 安装。它内置 AI SDK、JSON:API Resources 及原生向量搜索,支持属性驱动开发与队列路由,大幅提升开发效率。相比旧版,13.2.0 优化了缓存 TTL 管理与实时通信,无需 Redis 即可横向扩展。作为现代 Web 开发首选,它兼顾安全与极速体验,助您快速构建企业级应用。
下载
Repository方法命名聚焦数据动作:findBySlug()、withAuthorAndTags()、searchByKeywords(),不出现process、handle、validate这类词
返回值保持一致:要么全是Model/Collection,要么全是DTO(需显式转换),别混用
测试时Repository总报错找不到模型?
最常见的原因是模型没用use App\Models\Post;,而是用了use Illuminate\Database\Eloquent\Model;。Eloquent Repository里所有Post::query()调用都依赖具体模型类。
- 检查实现类里的
use语句,确保指向App\Models\XXX
- 测试时若用
RefreshDatabase,记得在Repository测试方法里手动Artisan::call('migrate')或使用内存SQLite(DB_CONNECTION=sqlite + database_path(':memory:'))
- 别在Repository里用
DB::table()绕过模型——这会让软删除、时间戳、访问器全部失效,也破坏了Eloquent抽象层
在getPublishedPosts()里调用Notification::send()
把订单创建+库存扣减+日志记录全塞进OrderRepository::createWithStockCheck()
返回数组而非Eloquent Collection或Model实例,导致后续无法链式调用->load()
业务规则(如“用户积分不足不能下单”)应放在Service层,Repository只负责提供user()->points和stock()->available
PHP中文网提供Laravel 13.2.0版本下载,Laravel框架 是基于 PHP 8.3+ 的高性能框架,官方推荐通过 Composer 安装。它内置 AI SDK、JSON:API Resources 及原生向量搜索,支持属性驱动开发与队列路由,大幅提升开发效率。相比旧版,13.2.0 优化了缓存 TTL 管理与实时通信,无需 Redis 即可横向扩展。作为现代 Web 开发首选,它兼顾安全与极速体验,助您快速构建企业级应用。
Repository方法命名聚焦数据动作:findBySlug()、withAuthorAndTags()、searchByKeywords(),不出现process、handle、validate这类词
返回值保持一致:要么全是Model/Collection,要么全是DTO(需显式转换),别混用
use App\Models\Post;,而是用了use Illuminate\Database\Eloquent\Model;。Eloquent Repository里所有Post::query()调用都依赖具体模型类。
- 检查实现类里的
use语句,确保指向App\Models\XXX - 测试时若用
RefreshDatabase,记得在Repository测试方法里手动Artisan::call('migrate')或使用内存SQLite(DB_CONNECTION=sqlite+database_path(':memory:')) - 别在Repository里用
DB::table()绕过模型——这会让软删除、时间戳、访问器全部失效,也破坏了Eloquent抽象层
真正卡住人的从来不是“要不要用Repository”,而是接口边界划在哪、谁该对哪段逻辑负责。一个Repository方法如果开始需要传5个参数、返回值要适配3种调用方、注释里写着“此处兼容旧版API”,那就该拆了。










