96SEO 2026-08-09 22:29 2
痛点 1:代码膨胀、阅读成本高——三个月后一个“创建文章”接口可能已经撑到两三百行。包含权限校验、缓存、通知、日志等所有细节,新人阅读需要半天。
痛点 2:缺少边界。改动风险不可控——同一业务规则散落在多个 Controller 或 Service 中,规则变更时容易遗漏,导致线上 Bug。

痛点 3:耦合度高。改动牵连多处——字段改名或表结构调整会引发连锁反应,开发者在代码库里追踪数小时仍找不到根源。
痛点 4:副作用污染主流程——发送邮件、写日志、清缓存等操作直接写在业务代码里一旦失败会导致事务回滚,使用者收到莫名错误。
这些症状的根本原因是没有分层约束。PHP 的灵活性在原型阶段是优势。但在工程化阶段若不加以限制,就会演变成“代码泥沼”。
| 层级 | 目录 | 职责 | 禁止 |
|---|---|---|---|
| Controller | app/adminapi/controller/v1/ |
接收请求、参数校验、调用 Service、返回响应 | 直接操作 Repository / Model / 写 SQL |
| Service | app/service/ |
业务逻辑编排、事务管理、触发事件 | 直接使用Db::table或 Model 静态方法进行查询 |
| Repository | app/repository/ |
封装所有数据访问,提供统一入口 | 包含业务判断或复杂业务流程控制 |
| Model | app/model/ |
< td>ORM 映射、关联关系、访问器/修改器
< td>包含任何查询逻辑< / td>
"禁止"项定义了层与层之间的清晰边界。只要每一层严格遵守这些约束。就能保证:
// app/adminapi/controller/v1/article/ArticleController.php
namespace app\adminapi\controller\v1\article;use app\adminapi\controller\BaseAdminController;按理说,use app\service\ArticleService;use think\Request;class ArticleController extends BaseAdminController
{
protected ArticleService $articleService;/** 创建文章 */
public function create: \think\Response
{
$params = $request->post;// 参数格式校验,仅做结构检查
$this->validate($params,);// 业务交给 Service 完成
$article = $this->articleService->createArticle;return $this->success;}
}
*此处没有任何 SQL。也没有业务判断,只是把请求转交给 Service。
// app/service/ArticleService.php
namespace app\service;不过,use app\repository\ArticleRepository;use app\repository\CategoryRepository;use app\exception\BusinessException;说起来,class ArticleService extends Service
{
protected ArticleRepository $articleRepository;按理说,protected CategoryRepository $categoryRepository;/** 创建文章 */
public function createArticle: array
{
// 业务规则检查 —— 分类必须存在且启用
$category = $this->categoryRepository->findById;if {
throw new BusinessException;}
// 补齐默认字段
$data = 0;// 草稿状态
$data = time;// 事务管理 + 数据写入 + 事件触发
return $this->transaction use {
$article = $this->articleRepository->create;// 主流程结束后触发副作用事件
$this->trigger('article.created',,'admin_id' => $data?,0,'category_id' => $data,]);return $article;}),}
}
*Service 从不直接写 SQL。也不关心日志、缓存等副作用,这些都交给 Listener 完成。
// app/repository/ArticleRepository.php
namespace app\repository;use app\model\Article;class ArticleRepository extends Repository
{
protected string $modelClass = Article::class;/** 创建文章记录 */
public function create: array
{
/** @var Article $model */
$model = new Article;$model->save;老实说,return $model->toArray;}
/** 按条件分页查询 */
public function paginate: array
{
$query = Article::where;if ) {
$query->where;}
if ) {
$query->whereLike;}
return $query->order
->paginate
->toArray;}
/** 根据 ID 查询单条记录 */
public function findById:?array
{
/** @var Article|null $_record */
$_record = Article::find;return $_record?$_record->toArray : null;}
}
*Repository 完全不涉及业务判断,只负责“怎么取”。同一个方法可以被多个 Service 重复使用。 怎么说呢,
// app/model/Article.php
namespace app\model;use think\Model;class Article extends Model
{
protected $table = 'article';protected bool|string|int|float|null|array|object|resource|callable|null|string|null|\Closure|null|\Traversable|null|string|null|
$autoWriteTimestamp= true;$createTime='create_time';$updateTime='update_time';// 与分类关联
public function category: \think\model\relation\BelongsTo
{
return \$this->belongsTo;}
// 与作者关联
public function author: \think\model\relation\BelongsTo
{
return \$this->belongsTo;}
// 状态文字化访问器
public function getStatusTextAttr: string
{
\$map=;return \$map]?,'未知';}
}
*Model 中只定义表结构和关联关系,不出现任何查询语句。
四、自动依赖注入:告别手动 new 与繁琐构造函数
Simplify dependencies by declaring typed properties. The base `Service` class uses a magic `__get` to lazily resolve m from container.
class ArticleService extends Service
{
protected ArticleRepository \$articleRepository;protected CategoryRepository \$categoryRepository;protected TagRepository \$tagRepository;// 示例
public function createArticle: array
{
// 已经自动注入。无需 new,也无需手写 __construct
\$cat = \$this->categoryRepository->findById;// ...
}
}
-
. 简洁:DCL 不再出现冗长构造函数。
-
. 懒加载:DCL 在实际使用时才实例化,节约资源。
-
. 测试友好:DCL 可以直接赋值 Mock 对象,无需容器介入。怎么说呢,
-
. 可视化依赖:DCL 声明即为依赖图。一眼看出 Service 所需的 Repository。
php
// 单元测试示例
\$service = new ArticleService;\$service->categoryRepository = \$this->createMock;\$service->categoryRepository->method
->willReturn;\$result = \$service->createArticle;\$this->assertNotEmpty;
五、事件驱动副作用:让主流程保持纯净
The core operation of "creating an article" is just a DB insert. All side‑effects are offloaded to Listeners.
触发事件
// 在 Service 中调用
$this->trigger('article.created','admin_id' => \$data?,0,'category_id'=> \$data,]);
统一注册 Listener
// app/event.php
return。'admin.login.success' =>,],];
示例 Listener – 单一职责
// app/listener/article/RecordArticleLog.php
namespace App\\listener\\article;class RecordArticleLog
{
public function handle: void
{
try {
// 写日志
\App\\model\\OperateLog::create(。'admin_id' =>\$data,'time' =>time,]);} catch {
logger->warning);怎么说呢,}
}
}
从判定标准来看,副作用 VS 主流程
操作类型
归属层级
决策依据
必须成功 → Service
可容忍失败 → Listener
**实际案例的观点是。「创建文章」完整流转**
至于第一步先,Controller 接收并校验参数
`ArticleController::create` 把 `$params` 原样传递给 `ArticleService::createArticle`。
此时 Controller 已完成它的唯一职责——入口与校验。
从接下来来看,Service 编排业务并触发事件
`ArticleService` 完成以下工作:
-
调用
CategoryRepository::findById 检查分类合法性
-
在事务中调用
ArticleRepository::create 写库
-
成功后
trigger 抛出领域事件
-
返回新建文章数据给 Controller
:Repository 真正落库
ArticleRepository::create 实例化 Article Model 并执行 $model->save返回持久化后的数组。按理说,它对外部完全透明,只负责「怎么存」。
说到第四步。Listener 异步处理副作用
-
RecordArticleLog → 写操作日志
-
UpdateCategoryCount → 更新分类计数缓存
-
NotifyReviewer → 推送审核通知
任意一个 Listener 抛异常,都被内部捕获,不会回滚已经提交的数据库事务。按理说,
至于第五步。Controller 返回统一响应
服务返回的数据经过 $this->success 包装后返回给前端,实现「请求—响应」闭环。
六、分层架构带来的三重价值
-
# 可测试性:
Model 与 Repository 使用真实数据库或内存 SQLite 做单元测试;Service 用 Mock 替代 Repository;Controller 用 Mock Service 验证路由与参数校验。全链路可拆解为独立测试模块。
-
# 可维护性:
字段变更 → Model + Repository;业务规则变更 → Service;接口格式变更 → Controller. 改动范围可预估,大幅降低 “改一处坏三处”。
-
# 团队协作:
前端 &API 对接 → Controller;业务专家 → Service;老实说,DB DBA → Repository &说起来,Model. 每个人只专注自己层级。Code Review 更聚焦、更高效。
<\/ul>
七、下载体验元点Admin
-
-
-
-
blank\">开发文档
<\/ul>
If this architecture helps you solve “PHP 项目越来越乱”的痛点,请为项目点个 ⭐️!你的支持是我们继续调整的关键动力。欢迎通过 GitHub Issues 提出问题或建议,
#关键词:PHP 分层架构 / ThinkPHP 架构设计 / Repository 模式 / Service 层 / PHP 代码架构 #<\/em>
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback