在应用开发过程中,使用最多的操作还是数据查询操作,凭借ThinkPHP的连贯操作的特性,可以使得查询操作变得更优雅和清晰,命名范围功能则是给模型操作定义了一系列的封装,让你更方便的操作数据。

命名范围功能的优势在于可以一次定义多次调用,并且在项目中也能起到分工配合的规范,避免开发人员在写CURD操作的时候出现问题,项目经理只需要合理的规划命名范围即可。

定义属性

要使用命名范围功能,主要涉及到模型类的_scope属性定义和scope连贯操作方法的使用。

我们首先定义_scope属性:

  1. namespace Home\Model;
  2. use Think\Model;
  3. class NewsModel extends Model {
  4. protected $_scope = array(
  5. // 命名范围normal
  6. 'normal'=>array(
  7. 'where'=>array('status'=>1),
  8. ),
  9. // 命名范围latest
  10. 'latest'=>array(
  11. 'order'=>'create_time DESC',
  12. 'limit'=>10,
  13. ),
  14. );
  15. }

_scope属性是一个数组,每个数组项表示定义一个命名范围,命名范围的定义格式为:

  1. '命名范围标识'=>array(
  2. '属性1'=>'值1',
  3. '属性2'=>'值2',
  4. ...
  5. )

命名范围标识:可以是任意的字符串,用于标识当前定义的命名范围名称。

命名范围支持的属性包括:

属性 描述
where 查询条件
field 查询字段
order 结果排序
table 查询表名
limit 结果限制
page 结果分页
having having查询
group group查询
lock 查询锁定
distinct 唯一查询
cache 查询缓存

每个命名范围的定义可以包括这些属性中一个或者多个。

方法调用

属性定义完成后,接下来就是使用scope方法进行命名范围的调用了,每调用一个命名范围,就相当于执行了命名范围中定义的相关操作选项对应的连贯操作方法。

调用某个命名范围

最简单的调用方式就直接调用某个命名范围,例如:

  1. $Model = D('News'); // 这里必须使用D方法 因为命名范围在模型里面定义
  2. $Model->scope('normal')->select();
  3. $Model->scope('latest')->select();

生成的SQL语句分别是:

  1. SELECT * FROM think_news WHERE status=1
  2. SELECT * FROM think_news ORDER BY create_time DESC LIMIT 10
调用多个命名范围

也可以支持同时调用多个命名范围定义,例如:

  1. $Model->scope('normal')->scope('latest')->select();

或者简化为:

  1. $Model->scope('normal,latest')->select();

生成的SQL都是:

  1. SELECT * FROM think_news WHERE status=1 ORDER BY create_time DESC LIMIT 10

如果两个命名范围的定义存在冲突,则后面调用的命名范围定义会覆盖前面的相同属性的定义。

如果调用的命名范围标识不存在,则会忽略该命名范围,例如:

  1. $Model->scope('normal,new')->select();

上面的命名范围中new是不存在的,因此只有normal命名范围生效,生成的SQL语句是:

  1. SELECT * FROM think_news WHERE status=1

默认命名范围

系统支持默认命名范围功能,如果你定义了一个default命名范围,例如:

  1. protected $_scope = array(
  2. // 默认的命名范围
  3. 'default'=>array(
  4. 'where'=>array('status'=>1),
  5. 'limit'=>10,
  6. ),
  7. );

那么调用default命名范围可以直接使用:

  1. $Model->scope()->select();

而无需再传入命名范围标识名

  1. $Model->scope('default')->select();

虽然这两种方式是等效的。

命名范围调整

如果你需要在normal命名范围的基础上增加额外的调整,可以使用:

  1. $Model->scope('normal',array('limit'=>5))->select();

生成的SQL语句是:

  1. SELECT * FROM think_news WHERE status=1 LIMIT 5

当然,也可以在两个命名范围的基础上进行调整,例如:

  1. $Model->scope('normal,latest',array('limit'=>5))->select();

生成的SQL是:

  1. SELECT * FROM think_news WHERE status=1 ORDER BY create_time DESC LIMIT 5
自定义命名范围

又或者,干脆不用任何现有的命名范围,我直接传入一个命名范围:

  1. $Model->scope(array('field'=>'id,title','limit'=>5,'where'=>'status=1','order'=>'create_time DESC'))->select();

这样,生成的SQL变成:

  1. SELECT id,title FROM think_news WHERE status=1 ORDER BY create_time DESC LIMIT 5
与连贯操作混合使用

dd马达

命名范围一样可以和之前的连贯操作混合使用,例如定义了命名范围_scope属性:

  1. protected $_scope = array(
  2. 'normal'=>array(
  3. 'where'=>array('status'=>1),
  4. 'field'=>'id,title',
  5. 'limit'=>10,
  6. ),
  7. );

然后在使用的时候,可以这样调用:

  1. $Model->scope('normal')->limit(8)->order('id desc')->select();

这样,生成的SQL变成:

  1. SELECT id,title FROM think_news WHERE status=1 ORDER BY id desc LIMIT 8

如果定义的命名范围和连贯操作的属性有冲突,则后面调用的会覆盖前面的。

如果是这样调用:

  1. $Model->limit(8)->scope('normal')->order('id desc')->select();

生成的SQL则是:

  1. SELECT id,title FROM think_news WHERE status=1 ORDER BY id desc LIMIT 10
动态调用

除了采用scope方法调用命名范围外,我们还支持直接调用命名范围名称的方式来动态调用,例如:

  1. $Model->scope('normal',array('limit'=>5))->select();

查询操作也可以采用:

  1. $Model->normal(array('limit'=>5))->select();

的方式调用。 normal(array('limit'=>5))表示调用normal命名范围,并且传入额外的array('limit'=>5)参数。

由于采用的是__call魔术方法机制,因此这样调用的前提是你定义的命名范围名称没有和现有操作方法冲突。

 

thinkphp 命名范围的更多相关文章

  1. Thinkphp命名规范

    1.类文件都是以.class.php为后缀(这里是指的ThinkPHP内部使用的类库文件,不代表外部加载的类库文件),使用驼峰法命名,并且首字母大写,例如 DbMysql.class.php: 2.类 ...

  2. thinkphp 命名规范

    目录和文件命名 目录和文件名采用 小写+下划线,并且以小写字母开头: 类库.函数文件统一以.php为后缀: 类的文件名均以命名空间定义,并且命名空间的路径和类库文件所在路径一致(包括大小写): 类名和 ...

  3. ThinkPHP import 类库导入 include PHP文件

    ThinkPHP 模拟了 Java 的类库导入机制,统一采用 import 方法进行类文件的加载.import 方法是 ThinkPHP 内建的类库和文件导入方法,提供了方便和灵活的文件导入机制,完全 ...

  4. 从" ThinkPHP 开发规范 "看 PHP 的命名规范和开发建议

    稍稍水一篇博客,摘抄自Think PHP 的开发规范,很有引导性,我们可以将这些规范实践到原生 PHP 中. 命名规范 使用ThinkPHP开发的过程中应该尽量遵循下列命名规范: 类文件都是以.cla ...

  5. ThinkPHP 模型(Model)命名规范

    一个小问题搞了好久:如果数据库的表名中有下划线,那么在用thinkphp做自动完成时注意Model类的命名要变成驼峰法,文件名和类名都要变.( 另外注意:只有使用create方法创建数据时才能调用到自 ...

  6. 这次一定理清晰ThinkPHP之中的模型、数据库之间命名规范

    ServiceSiteModel.class.php 这个模型操控的数据库是service_site表: <?php namespace Admin\Model; use Think\Model ...

  7. thinkphp学习笔记1—目录结构和命名规则

    原文:thinkphp学习笔记1-目录结构和命名规则 最近开始学习thinkphp,在下不才,很多的问题看不明白所以想拿出来,恕我大胆发在首页上,希望看到的人能为我答疑解惑,这样大家有个互动,学起来快 ...

  8. ThinkPHP中的模型命名

    当我们创建一个UserModel类的时候,其实已经遵循了系统的约定.ThinkPHP要求数据库的表名和模型类的命名遵循一定的规范,首先数据库的表名和字段全部采用小写形式,模型类的命名规则是除去表前缀的 ...

  9. THINKPHP源码学习--------文件上传类

    TP图片上传类的理解 在做自己项目上传图片的时候一直都有用到TP的上传图片类,所以要进入源码探索一下. 文件目录:./THinkPHP/Library/Think/Upload.class.php n ...

随机推荐

  1. 27. USART, Universal synchronous asynchronous receiver transmitter

    27.1 USART introduction 通用同步异步接收发射机(USART)对需要NRZ异步串行数据格式行业标准的外部设备,提供了一个灵活的全双工数据交换的方法.USART使用分数波特率生成器 ...

  2. Docker Api 实测

    好久没写博客,工作中想着未来部门需要对docker进行维护相对麻烦,而且,网络上也缺少一些合适的项目,于是准备筹划自己动手.先找到了Docker 的API文档,地址是:https://docs.doc ...

  3. HDFS API 操作实例(一) HDFS读写操作

    1. 读取HDFS文件 1.1 字符读取HDFS上的文件 Configuration conf = new Configuration(); Path path = new Path(pathstr) ...

  4. 数据分析相关概念(numpy)

    矢量 矢量是指一堆形成的集合. 多维数组也叫做矢量化计算. 单独一个数叫做标量 例: import datetime as dt import numpy as np n2=10000 start2 ...

  5. HTTP协议:响应消息

    一.请求消息:客户端发送给服务器端的数据 数据格式: 1.请求行 2.请求头 3.请求空行 4.请求体 二.响应消息:服务器端发送给客户的数据 数据格式: 1.响应行: 1.组成:协议/版本 响应状态 ...

  6. sparkStreaming的transformation和action详解

    根据Spark官方文档中的描述,在Spark Streaming应用中,一个DStream对象可以调用多种操作,主要分为以下几类 Transformations Window Operations J ...

  7. python库之lightgbm

    一.安装 https://blog.csdn.net/qq_40317897/article/details/81021958 参考文献: [1].LightGBM中文文档 https://light ...

  8. vue项目 上传到git

    1. git add . 效果: 2. git commit -m '' 3. git push 效果: 4.在码云上就可以看到修改啦 2018-05-19  08:52:52

  9. Largest Submatrix

    Largest Submatrix 给出一个\(n\times m\)的网格,网格里只放有字符a,b,c,d,w,x,,z,现在你可以将其中的w换成a,b,把x换成b,c,把y换成a,c,把z换成a, ...

  10. 【BZOJ2298】【luoguP2519】problem a

    description 一次考试共有n个人参加,第i个人说:"有ai个人分数比我高,bi个人分数比我低."问最少有几个人没有说真话(可能有相同的分数) analysis 这题转化模 ...