fengahan
backend下的index.php没有吧
backend下的index.php没有吧
- fengahan 2018-08-21 已签到连续签到1天,获得了5个金钱
问题场景
我们用Yii2的ActiveRecord功能非常的方便,假如我们有个Model叫Student,那么ActiveQuery可以通过这种方式轻便地获得:$query = Student::find();
然后,我们就可以在$query上继续使用各种方法添加SQL Clause:$query->where(['gender' => 'male' ]); //选择男生
$query->where(['>', age' => '18' ]); //选择年龄大于18的
如果这条学生的记录需要审核,还可能有
$query->where([''check_status' => '1' ]); // 1-审核通过
最后,使用all()或者one()获取结果。这是使用Yii2的小伙伴们天天在做的事情。
但是,笔者有时也觉得动不动就写一长串的where条件挺讨厌的,一则是太长,二则是可阅读性也不大好,['check_status' => '1' ]这类的条件有时并不容易看出是何种意图。所以得找一种更为简便的方法就变得很有必要。
优化
写出面向对象化的代码是笔者的追求,我们希望能这样的去做查询:Student::male()->all(); //选择男生
Student::checked()->male()->all(); //选择审核通过的男生
看不到那么多长长的where语句,就像伪代码一样良好的可读性,就算没用用过Yii2的小伙伴也能看懂是啥意思。如果能能这样去写代码,你愿不愿意?实现
要说到如何实现,那就得依赖强大的魔术方法call()和callStatic()了。我们直接抛出代码,让大家看看是怎么实现的。定义Scope方法
首先,需要在Model内部,定义一些Scope方法,用以封装特定的where条件集合,表示相对常用筛选条件。 Scope方法的格式为public function xxxScope($param1, $param2,..., \yii\db\ActiveQuery $query)
{
return $query->where(['attr1' => $param1])->where(['attr2' => $param2]);
}
注意,xxxScope方法的前面的$param1, $param2,...都是可选的,最后一个参数一定是AQ的一个实例$query,用以接收where条件,最后需要return将其返回。