## 查询范围
对于一些常用的查询条件,我们可以封装成查询范围来进行方便的调用。
例如,邮箱地址为`thinkphp@qq.com`和status为1这两个常用查询条件,可以定义为模型类的两个查询范围方法:
```
<pre class="calibre18">
```
<span class="hljs-operator"><span class="hljs-number"><?php</span><span class="hljs-keyword">namespace</span> <span class="hljs-title">app</span>\<span class="hljs-title">index</span>\<span class="hljs-title">model</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">think</span>\<span class="hljs-title">Model</span>;
<span class="hljs-operator"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Model</span></span>{
<span class="hljs-comment">// 定义类型转换</span><span class="hljs-keyword">protected</span> <span class="hljs-regexp">$type</span> = [
<span class="hljs-string">'birthday'</span> => <span class="hljs-string">'timestamp:Y/m/d'</span>,
];
<span class="hljs-comment">// 定义自动完成的属性</span><span class="hljs-keyword">protected</span> <span class="hljs-regexp">$insert</span> = [<span class="hljs-string">'status'</span>];
<span class="hljs-comment">// status修改器</span><span class="hljs-keyword">protected</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setStatusAttr</span><span class="hljs-number">(<span class="hljs-regexp">$value</span>, <span class="hljs-regexp">$data</span>)</span></span>{
<span class="hljs-keyword">return</span> <span class="hljs-string">'流年'</span> == <span class="hljs-regexp">$data</span>[<span class="hljs-string">'nickname'</span>] ? <span class="hljs-number">1</span> : <span class="hljs-number">2</span>;
}
<span class="hljs-comment">// status读取器</span><span class="hljs-keyword">protected</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getStatusAttr</span><span class="hljs-number">(<span class="hljs-regexp">$value</span>)</span></span>{
<span class="hljs-regexp">$status</span> = [-<span class="hljs-number">1</span> => <span class="hljs-string">'删除'</span>, <span class="hljs-number">0</span> => <span class="hljs-string">'禁用'</span>, <span class="hljs-number">1</span> => <span class="hljs-string">'正常'</span>, <span class="hljs-number">2</span> => <span class="hljs-string">'待审核'</span>];
<span class="hljs-keyword">return</span> <span class="hljs-regexp">$status</span>[<span class="hljs-regexp">$value</span>];
}
<span class="hljs-comment">// email查询</span><span class="hljs-keyword">protected</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">scopeEmail</span><span class="hljs-number">(<span class="hljs-regexp">$query</span>)</span></span>{
<span class="hljs-regexp">$query</span>->where(<span class="hljs-string">'email'</span>, <span class="hljs-string">'thinkphp@qq.com'</span>);
}
<span class="hljs-comment">// status查询</span><span class="hljs-keyword">protected</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">scopeStatus</span><span class="hljs-number">(<span class="hljs-regexp">$query</span>)</span></span>{
<span class="hljs-regexp">$query</span>->where(<span class="hljs-string">'status'</span>, <span class="hljs-number">1</span>);
}
}</span>
```
```
查询范围方法的定义规范为:
> ### scope + 查询范围名称
我们修改控制器的index方法如下:
```
<pre class="calibre18">
```
<span class="hljs-comment">// 根据查询范围获取用户数据列表</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">index</span><span class="hljs-number">()</span></span>{
<span class="hljs-regexp">$list</span> = UserModel::scope(<span class="hljs-string">'email,status'</span>)->all();
<span class="hljs-keyword">foreach</span> (<span class="hljs-regexp">$list</span> <span class="hljs-keyword">as</span> <span class="hljs-regexp">$user</span>) {
<span class="hljs-keyword">echo</span> <span class="hljs-regexp">$user</span>->nickname . <span class="hljs-string">'<br/>'</span>;
<span class="hljs-keyword">echo</span> <span class="hljs-regexp">$user</span>->email . <span class="hljs-string">'<br/>'</span>;
<span class="hljs-keyword">echo</span> <span class="hljs-regexp">$user</span>->birthday . <span class="hljs-string">'<br/>'</span>;
<span class="hljs-keyword">echo</span> <span class="hljs-regexp">$user</span>->status . <span class="hljs-string">'<br/>'</span>;
<span class="hljs-keyword">echo</span> <span class="hljs-string">'-------------------------------------<br/>'</span>;
}
}
```
```
最后查询的SQL语句是:
```
<pre class="calibre18">
```
<span class="hljs-operator">SELECT * <span class="hljs-keyword">FROM</span> <span class="hljs-string">`think_user`</span> <span class="hljs-keyword">WHERE</span> <span class="hljs-string">`email`</span> = <span class="hljs-string">'thinkphp@qq.com'</span> <span class="hljs-keyword">AND</span> <span class="hljs-string">`status`</span> = <span class="hljs-number">1</span> </span>
```
```
支持多次调用`scope`方法,并且可以追加新的查询及链式操作,例如:
```
<pre class="calibre18">
```
<span class="hljs-comment">// 根据查询范围获取用户数据列表</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">index</span><span class="hljs-number">()</span></span>{
<span class="hljs-comment">// </span><span class="hljs-regexp">$list</span> = UserModel::scope(<span class="hljs-string">'email'</span>)
->scope(<span class="hljs-string">'status'</span>)
->scope(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-number">(<span class="hljs-regexp">$query</span>)</span> </span>{
<span class="hljs-regexp">$query</span>->order(<span class="hljs-string">'id'</span>, <span class="hljs-string">'desc'</span>);
})
->all();
<span class="hljs-keyword">foreach</span> (<span class="hljs-regexp">$list</span> <span class="hljs-keyword">as</span> <span class="hljs-regexp">$user</span>) {
<span class="hljs-keyword">echo</span> <span class="hljs-regexp">$user</span>->nickname . <span class="hljs-string">'<br/>'</span>;
<span class="hljs-keyword">echo</span> <span class="hljs-regexp">$user</span>->email . <span class="hljs-string">'<br/>'</span>;
<span class="hljs-keyword">echo</span> <span class="hljs-regexp">$user</span>->birthday . <span class="hljs-string">'<br/>'</span>;
<span class="hljs-keyword">echo</span> <span class="hljs-regexp">$user</span>->status . <span class="hljs-string">'<br/>'</span>;
<span class="hljs-keyword">echo</span> <span class="hljs-string">'-------------------------------------<br/>'</span>;
}
}
```
```
上面的scope方法使用了闭包,闭包里面支持所有的链式操作方法。
最后生成的SQL语句是:
```
<pre class="calibre18">
```
<span class="hljs-operator">SELECT * <span class="hljs-keyword">FROM</span> <span class="hljs-string">`think_user`</span> <span class="hljs-keyword">WHERE</span> <span class="hljs-string">`email`</span> = <span class="hljs-string">'thinkphp@qq.com'</span> <span class="hljs-keyword">AND</span> <span class="hljs-string">`status`</span> = <span class="hljs-number">1</span> <span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> <span class="hljs-string">`id`</span> <span class="hljs-keyword">desc</span> </span>
```
```
查询范围方法支持额外的参数,例如`scopeEmail`方法改为:
```
<pre class="calibre18">
```
<span class="hljs-comment">// email查询</span><span class="hljs-keyword">protected</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">scopeEmail</span><span class="hljs-number">(<span class="hljs-regexp">$query</span>, <span class="hljs-regexp">$email</span> = <span class="hljs-string">''</span>)</span></span>{
<span class="hljs-regexp">$query</span>->where(<span class="hljs-string">'email'</span>, <span class="hljs-regexp">$email</span>);
}
```
```
> 查询范围的方法的第一个参数必须是查询对象,并且支持多个额外参数。
然后,使用下面的方式调用即可:
```
<pre class="calibre18">
```
<span class="hljs-regexp">$list</span> = UserModel::scope(<span class="hljs-string">'email'</span>,<span class="hljs-string">'thinkphp@qq.com'</span>)->all();
```
```
## 全局查询范围
可以给模型定义全局的查询范围,在模型类添加一个静态的`base`方法即可,例如我们给模型类增加一个全局查询范围,用于查询状态为1的数据:
```
<pre class="calibre18">
```
<span class="hljs-operator"><span class="hljs-number"><?php</span><span class="hljs-keyword">namespace</span> <span class="hljs-title">app</span>\<span class="hljs-title">index</span>\<span class="hljs-title">model</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">think</span>\<span class="hljs-title">Model</span>;
<span class="hljs-operator"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Model</span></span>{
<span class="hljs-comment">// 定义类型转换</span><span class="hljs-keyword">protected</span> <span class="hljs-regexp">$type</span> = [
<span class="hljs-string">'birthday'</span> => <span class="hljs-string">'timestamp:Y/m/d'</span>,
];
<span class="hljs-comment">// 定义自动完成的属性</span><span class="hljs-keyword">protected</span> <span class="hljs-regexp">$insert</span> = [<span class="hljs-string">'status'</span>];
<span class="hljs-comment">// status修改器</span><span class="hljs-keyword">protected</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setStatusAttr</span><span class="hljs-number">(<span class="hljs-regexp">$value</span>, <span class="hljs-regexp">$data</span>)</span></span>{
<span class="hljs-keyword">return</span> <span class="hljs-string">'流年'</span> == <span class="hljs-regexp">$data</span>[<span class="hljs-string">'nickname'</span>] ? <span class="hljs-number">1</span> : <span class="hljs-number">2</span>;
}
<span class="hljs-comment">// status读取器</span><span class="hljs-keyword">protected</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getStatusAttr</span><span class="hljs-number">(<span class="hljs-regexp">$value</span>)</span></span>{
<span class="hljs-regexp">$status</span> = [-<span class="hljs-number">1</span> => <span class="hljs-string">'删除'</span>, <span class="hljs-number">0</span> => <span class="hljs-string">'禁用'</span>, <span class="hljs-number">1</span> => <span class="hljs-string">'正常'</span>, <span class="hljs-number">2</span> => <span class="hljs-string">'待审核'</span>];
<span class="hljs-keyword">return</span> <span class="hljs-regexp">$status</span>[<span class="hljs-regexp">$value</span>];
}
<span class="hljs-comment">// email查询</span><span class="hljs-keyword">protected</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">scopeEmail</span><span class="hljs-number">(<span class="hljs-regexp">$query</span>)</span></span>{
<span class="hljs-regexp">$query</span>->where(<span class="hljs-string">'email'</span>, <span class="hljs-string">'thinkphp@qq.com'</span>);
}
<span class="hljs-comment">// 全局查询范围</span><span class="hljs-keyword">protected</span> <span class="hljs-keyword">static</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">base</span><span class="hljs-number">(<span class="hljs-regexp">$query</span>)</span></span>{
<span class="hljs-comment">// 查询状态为1的数据</span><span class="hljs-regexp">$query</span>->where(<span class="hljs-string">'status'</span>,<span class="hljs-number">1</span>);
}
}</span>
```
```
当使用下面的查询操作
```
<pre class="calibre18">
```
<span class="hljs-operator"><span class="hljs-title1">UserModel</span>:<span class="hljs-string">:<span class="hljs-function">scope</span>(<span class="hljs-operator">'email'</span>)-><span class="hljs-function">all</span>()</span></span>;
```
```
最后生成的SQL语句是:
```
<pre class="calibre18">
```
<span class="hljs-operator">SELECT * <span class="hljs-keyword">FROM</span> <span class="hljs-string">`think_user`</span> <span class="hljs-keyword">WHERE</span> <span class="hljs-string">`email`</span> = <span class="hljs-string">'thinkphp@qq.com'</span> <span class="hljs-keyword">AND</span> <span class="hljs-string">`status`</span> = <span class="hljs-number">1</span> <span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> <span class="hljs-string">`id`</span> <span class="hljs-keyword">desc</span> </span>
```
```
每次查询都会自动带上全局查询范围的查询条件。
- 脕茫隆垄脨貌脩脭
- 脕茫隆垄脨貌脩脭
- 脪禄隆垄禄霉麓隆
- 脪禄隆垄禄霉麓隆
- 露镁隆垄URL潞脥脗路脫脡
- 露镁隆垄URL潞脥脗路脫脡
- 脠媒隆垄脟毛脟贸潞脥脧矛脫娄
- 脠媒隆垄脟毛脟贸潞脥脧矛脫娄
- 脣脛隆垄脢媒戮脻驴芒
- 脣脛隆垄脢媒戮脻驴芒
- 脦氓隆垄虏茅脩炉脫茂脩脭
- 脦氓隆垄虏茅脩炉脫茂脩脭
- 脕霉隆垄脛拢脨脥潞脥鹿脴脕陋
- 拢篓1拢漏脛拢脨脥露篓脪氓
- 拢篓2拢漏禄霉麓隆虏脵脳梅
- 拢篓3拢漏露脕脠隆脝梅潞脥脨脼赂脛脝梅
- 拢篓4拢漏脌脿脨脥脳陋禄禄潞脥脳脭露炉脥锚鲁脡
- 拢篓5拢漏虏茅脩炉路露脦搂
- 拢篓6拢漏脢盲脠毛潞脥脩茅脰陇
- 拢篓7拢漏鹿脴脕陋
- 拢篓8拢漏脛拢脨脥脢盲鲁枚
- 脝脽隆垄脢脫脥录潞脥脛拢掳氓
- 脝脽隆垄脢脫脥录潞脥脛拢掳氓
- 掳脣隆垄碌梅脢脭潞脥脠脮脰戮
- 掳脣隆垄碌梅脢脭潞脥脠脮脰戮
- 戮脜隆垄API驴陋路垄
- 戮脜隆垄API驴陋路垄
- 脢庐隆垄脙眉脕卯脨脨鹿陇戮脽
- 脢庐隆垄脙眉脕卯脨脨鹿陇戮脽
- 脢庐脪禄隆垄脌漏脮鹿
- 脢庐脪禄隆垄脌漏脮鹿
- 脢庐露镁隆垄脭脫脧卯
- Cookie
- Session
- 碌楼脭陋虏芒脢脭
- 脥录脧帽麓娄脌铆
- 脦脛录镁脡脧麓芦
- 脩茅脰陇脗毛
- 赂陆脗录
- A隆垄鲁拢录没脦脢脤芒录炉
- B隆垄3.2潞脥5.0脟酶卤冒
- C隆垄脰煤脢脰潞炉脢媒
- 路卢脥芒脝陋拢潞脩搂脧掳ThinkPHP5碌脛脮媒脠路脳脣脢脝
- 路卢脥芒脝陋拢潞脩搂脧掳ThinkPHP5碌脛脮媒脠路脳脣脢脝