thinkphp的mvc是依赖命名空间、psr-4加载和类继承的真实职责分离体系,model须继承think\model封装业务规则,controller须继承think\controller仅调度,view须纯模板输出且变量默认不可信,越界即破坏可测试性与可维护性。

ThinkPHP 的 MVC 不是目录摆设,而是靠命名空间、PSR-4 自动加载和类继承机制真实落地的职责分离体系。Model 必须继承 think\Model,Controller 必须继承 think\Controller,View 文件必须放在 app/view/ 下且只允许变量输出——不满足这些约定,MVC 就会失效。
Model 层不是“表映射”,而是业务逻辑容器
很多人把 Model 当成数据库表的搬运工,直接在 Controller 里写 $user->where('id', 1)->find(),这是错的。Model 应该封装完整业务规则:
- 密码修改必须走
$user->changePassword($raw),而不是在 Controller 里调Hash::make() - 关联定义(如
hasOne('Profile'))写在 Model 类内,View 和 Controller 不感知 JOIN 实现 - 验证规则优先写进模型的
$validate属性,或用独立验证器配合validate(true)自动触发 - 敏感字段加密要声明
protected $encrypt = ['bank_card'],而不是手动加解密
Controller 只做调度,禁止掺杂业务逻辑
Controller 方法超过 5 行代码,基本说明它越界了。常见错误包括:
- 在 Controller 里手写 SQL 或遍历数组格式化数据
- 把订单创建逻辑全塞进
OrderController->create(),而不是调用$orderService->create($data) - 用
$_POST直接取参,没走$this->request->param()或input() - 返回 HTML 字符串(如
echo '<div>...</div>'),而不是return view('order/success', $data)或return json(...)
View 层必须“纯模板”,所有变量默认不可信
模板里出现 <?php if(...) { ... } ?> 或 {$user->getBalance()} 就已破坏 MVC。正确做法是:
- 所有数据由 Controller 显式
assign()传入,模板只用{$name}或{:htmlspecialchars($name)} - 禁止在
{include file='xxx'}中传递运行时逻辑,include 只能静态复用区块 - 前后端分离项目中,View 可退化为 JSON 响应,
app/view/目录甚至可以为空 - 日期、金额等格式化统一用内置标签,如
{:date('Y-m-d H:i', $time)},不写原生date()
服务层(Service)是 MVC 的隐性支柱
ThinkPHP 官方文档没强制要求 Service 目录,但复杂项目必须补上。控制器直接调 Model 是危险信号:
- 用户身份校验(如
$order->user_id === $this->userId)必须在 Service 层做,不能放 Controller - 库存扣减、支付回调签名验证、Redis 分布式锁,都该封装在 Service 方法里
- Service 类通过
app('order_service')或依赖注入获取,避免 new 实例 - 日志记录要脱敏,手机号存
138****1234,身份证只存哈希值
真正卡住 MVC 落地的,不是语法,而是每层“能做什么、不能做什么”的边界意识。Model 里写一句 Db::query(),Controller 里多一个 foreach,View 里加个 if 判断——这些看似微小的越界,会在三个月后让整个模块无法单元测试、无法替换数据库、无法做前后端分离。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











