💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
## 查询范围 对于一些常用的查询条件,我们可以封装成查询范围来进行方便的调用。 例如,邮箱地址为`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> ``` ``` 每次查询都会自动带上全局查询范围的查询条件。