前缀scope ,后缀自定义,在调用时吧后缀当做参数即可。
public function scopeMale($query) { $query->where(\'gender\',\'男\') ->field(\'id,username,gender,email\') ->limit(5); } $user = model\UserModel::scope(\'male\')->select(); return "<hr>".Db::getLastSql()."<hr>".$user; public function scopeEmail($query, $value) { $query->where(\'email\',\'like\',\'%\'.$value.\'%\'); } $user = UserModel::scope(\'email\',\'xiao\')->select(); return "<hr>".Db::getLastSql()."<hr>".$user;scope() 的第一个参数是调用的封装方法,第二个参数是封装方法可以接收的数据
支持多个查询封装方法连缀调用
$user = UserModel::scope(\'email\',\'xiao\') ->scope(\'price\',80) ->select(); return "<hr>".Db::getLastSql()."<hr>".$user;在使用查找范围scope()后,指定使用find() select()查询;
在模型类中的查询封装方法中可以使用包括修改器、获取器等在内的模型操作方法。
public function getGenderAttr($value,$data) { $gender = [\'男\'=>\'纯爷们\',\'女\'=>\'小姑娘\']; return $gender[$value]; } public function scopeMale($query) { $query->where(\'gender\',\'男\') ->field(\'id,username,gender,email\') ->limit(5); } 全局查找范围支持在模型中设置globaScope属性,定义全局查找范围
class User extends Model { // 定义全局的查询范围 protected $globalScope = [\'status\']; public function scopeStatus($query) { $query->where(\'status\',1); } }然后,执行下面的代码:
$user = User::find(1);最终的查询条件会是
status = 1 AND id = 1如果需要动态关闭所有的全局查询范围,可以使用:
// 关闭全局查询范围 User::withoutGlobalScope()->select();可以使用withoutGlobalScope方法动态关闭部分全局查询范围。
User::withoutGlobalScope([\'status\'])->select(); 模型搜索器搜索器用于封装字段或搜索标识的表达式,类似查找范围
一个搜索器对应模型的一个特殊方法
命名规范search[FieldName]Attr()
User模型定义name字段和时间字段的搜索器,可以使用:
class User extends Model { public function searchNameAttr($query, $value, $data) { $query->where(\'name\',\'like\', $value . \'%\'); } public function searchCreateTimeAttr($query, $value, $data) { $query->whereBetweenTime(\'create_time\', $value[0], $value[1]); } }然后,我们可以使用下面的查询
User::withSearch([\'name\',\'create_time\'], [ \'name\' => \'think\', \'create_time\' => [\'2018-8-1\',\'2018-8-5\'], \'status\' => 1 ])->select();最终生成的SQL语句类似于
SELECT * FROM `think_user` WHERE `name` LIKE \'think%\' AND create_time` BETWEEN \'2018-08-01 00:00:00\' AND \'2018-08-05 00:00:00\'可以看到查询条件中并没有status字段的数据,因此可以很好的避免表单的非法查询条件传入,在这个示例中仅能使用name和create_time条件进行查询。
事实上,除了在搜索器中使用查询表达式外,还可以使用其它的任何查询构造器以及链式操作。
例如,你需要通过表单定义的排序字段进行搜索结果的排序,可以使用
class User extends Model { public function searchNameAttr($query, $value, $data) { $query->where(\'name\',\'like\', $value . \'%\'); if (isset($data[\'sort\'])) { $query->order($data[\'sort\']); } } public function searchCreateTimeAttr($query, $value, $data) { $query->whereBetweenTime(\'create_time\', $value[0], $value[1]); } }然后,我们可以使用下面的查询
User::withSearch([\'name\',\'create_time\', \'status\'], [ \'name\' => \'think\', \'create_time\' => [\'2018-8-1\',\'2018-8-5\'], \'status\' => 1, \'sort\' => [\'status\'=>\'desc\'], ]) ->select();最终查询的SQL可能是
SELECT * FROM `think_user` WHERE `name` LIKE \'think%\' AND `create_time` BETWEEN \'2018-08-01 00:00:00\' AND \'2018-08-05 00:00:00\' ORDER BY `status` DESC你可以给搜索器定义字段别名,例如:
User::withSearch([\'name\'=>\'nickname\',\'create_time\', \'status\'], [ \'nickname\' => \'think\', \'create_time\' => [\'2018-8-1\',\'2018-8-5\'], \'status\' => 1, \'sort\' => [\'status\'=>\'desc\'], ]) ->select();搜索器通常会和查询范围进行比较,搜索器无论定义了多少,只需要一次调用,查询范围如果需要组合查询的时候就需要多次调用
模型数据集数据集直接继承collection类,和数据的数据集方式一样、操作一样。
参照官方技术文档
模型自动时间戳系统支持自动写入创建和更新的时间戳字段(默认会关闭),具体配置方法:
全局开启:在database.php文件中修改auto_timestamp为truely
在模型类中单独开启自动时间戳:$autoWriteTimestamp
class User extends Model { protected $autoWriteTimestamp = true; }也或者单独关闭自动时间戳
class User extends Model { protected $autoWriteTimestamp = false; }