1. 主页 > 好文章

ThinkPHP常用方法最佳实践:控制器与模型高效调用指南


哎,你的控制器是不是正在"996加班"?

刚入门的小白总爱把业务逻辑全塞进控制器,活生生把控制器搞成"万能垃圾桶"。??记住喽,控制器就是个快递小哥??——它的任务是把用户请求(包裹)准确送到模型(仓库)处理,再把结果(派送单)返回给视图。举个栗子:用户提交订单时,控制器只负责接收数据,验证身份这种脏活累活应该交给模型!

??_控制器与模型分工对照表_??

场景该由谁干?错误示范正确操作
用户登录验证模型在控制器写SQL查询模型里封装checkLogin方法
订单金额计算模型控制器里做加减乘除模型定义calculatePrice
页面跳转逻辑控制器在模型里写redirect控制器调用模型后跳转

模型方法取名有玄机?试试这个命名公式

新手最爱用aaa()bbb()这种抽象方法名,三个月后自己都看不懂。教你个万能公式:??动词+名词+业务场景??。比如处理用户积分的addUserPointsAfterPayment(),看着长但绝对省去后期80%的沟通成本。

举个真实案例:
张三在模型里写了个doSomething()方法处理优惠券发放,结果李四维护时以为是处理退款,直接引发线上事故。要是当初取名sendCouponAfterOrderSuccess(),这场面压根不会发生!


控制器调用模型的三大"正确姿势"

  1. ??基础版:直接实例化??
    $user = new \app\model\User();
    适合场景:临时用一两次的简单操作,但长期使用会导致代码臃肿

  2. ??进阶版:依赖注入??

    public function index(User $userModel) {
        $userModel->getProfile();
    }

    优点:自动实例化+方便单元测试,TP6开始强烈推荐

  3. ??高阶版:门面模式??
    \app\facade\UserFacade::getLatestOrders();
    适合跨模块调用,像点外卖一样随用随取


模型关联查询的"防坑指南"

遇到过N+1查询问题吗?就是获取用户列表时,循环查询每个用户的订单数据。教你两招绝杀:

??方法一:预加载大法??

// 控制器
User::with('orders')->select();

模型里定义好hasMany关联,一次查询搞定用户和订单数据

??方法二:作用域封装??

// 模型
public function scopeWithOrders($query) {
    $query->with('orders');
}
// 控制器
User::withOrders()->select();

把常用查询打包成"快捷指令",团队协作时特别香


个人观点时间

用了三年ThinkPHP后发现,??控制器的理想状态应该是"瘦得能穿进XS码"??。那些在控制器里写满SQL操作的老哥,就像非要在客厅炒菜的装修师傅——不是不能做,但迟早把整个家搞得油烟弥漫。下次写控制器时不妨自问:这段代码要是换成其他开发者,能不能在10秒内看懂调用关系?如果答案是否定的,赶紧把逻辑往模型里搬吧!

最后送大家一句话:??好的代码不是写出来的,是"搬"出来的??——把正确的代码搬到正确的位置,这才是ThinkPHP最佳实践的精髓。

本文由嘻道妙招独家原创,未经允许,严禁转载