ThinkPHP3.1新特性之命名范围的使用


Posted in PHP onJune 19, 2014

ThinkPHP3.1的命名范围功能,给模型操作提供了一系列的(连贯操作)封装,让你更方便的查询和操作数据。下面我们就来具体了解下这一用法。

1.定义属性

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

class NewsModel extends Model {
  protected $_scope = array(
    // 命名范围normal
    'normal'=>array(
      'where'=>array('status'=>1),
    ),
    // 命名范围latest
    'latest'=>array(
      'order'=>'create_time DESC',
      'limit'=>10,
    ),
  );
 }

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

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

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

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

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

 

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

3.方法调用

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

调用某个命名范围

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

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

生成的SQL语句分别是:

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

调用多个命名范围

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

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

或者简化为:

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

生成的SQL都是:

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

如果两个命名范围的定义存在冲突,则后面调用的命名范围定义会覆盖前面的相同属性的定义。
如果调用的命名范围标识不存在,则会忽略该命名范围,例如:

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

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

SELECT * FROM think_news WHERE status=1

4.默认命名范围

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

  

protected $_scope = array(
    // 默认的命名范围
    'default'=>array(
      'where'=>array('status'=>1),
      'limit'=>10,
    ),
  );

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

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

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

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

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

命名范围调整

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

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

生成的SQL语句是:

SELECT * FROM think_news WHERE status=1 LIMIT 5

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

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

生成的SQL是:

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

自定义命名范围

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

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

这样,生成的SQL变成:

SELECT id,title FROM think_news WHERE status=1 ORDER BY create_time DESC LIMIT 5

5.与连贯操作混合使用

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

protected $_scope = array(
  'normal'=>array(
    'where'=>array('status'=>1),
    'field'=>'id,title',
    'limit'=>10,
  ),
 );

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

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

这样,生成的SQL变成:

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

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

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

生成的SQL则是:

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

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

PHP 相关文章推荐
一个程序下载的管理程序(三)
Oct 09 PHP
PHP 设计模式之观察者模式介绍
Feb 22 PHP
解析PHP跳出循环的方法以及continue、break、exit的区别介绍
Jul 01 PHP
php清空(删除)指定目录下的文件,不删除目录文件夹的实现代码
Sep 04 PHP
PHP使用PDO连接ACCESS数据库
Mar 05 PHP
PHP使用fopen与file_get_contents读取文件实例分享
Mar 04 PHP
Yii遍历行下每列数据的方法
Oct 17 PHP
php  PATH_SEPARATOR判断当前服务器系统类型实例
Oct 28 PHP
php封装的验证码类分享
Feb 26 PHP
php7函数,声明,返回值等新特性介绍
May 25 PHP
ThinkPHP 3使用OSS的方法
Jul 19 PHP
laravel 根据不同组织加载不同视图的实现
Oct 14 PHP
ThinkPHP3.1新特性之Action参数绑定
Jun 19 #PHP
ThinkPHP3.1新特性之多层MVC的支持
Jun 19 #PHP
php定界符
Jun 19 #PHP
php获取网页中图片、DIV内容的简单方法
Jun 19 #PHP
PHP两种去掉数组重复值的方法比较
Jun 19 #PHP
PHP封装的一个支持HTML、JS、PHP重定向的多功能跳转函数
Jun 19 #PHP
ThinkPHP3.1基础知识快速入门
Jun 19 #PHP
You might like
PHP中通过ADO调用Access数据库的方法测试不通过
2006/12/31 PHP
根据中文裁减字符串函数的php代码
2013/12/03 PHP
php使用pack处理二进制文件的方法
2014/07/03 PHP
PHP图片处理之图片背景、画布操作
2014/11/19 PHP
php常用表单验证类用法实例
2015/06/18 PHP
使用PHP下载CSS文件中的所有图片【几行代码即可实现】
2016/12/14 PHP
javascript URL锚点取值方法
2009/02/25 Javascript
jQuery.clean使用方法及思路分析
2013/01/07 Javascript
在javascript中随机数 math random如何生成指定范围数值的随机数
2015/10/21 Javascript
JS实现超精简的链接列表在固定区域内滚动效果代码
2015/11/04 Javascript
AngularJS框架中的双向数据绑定机制详解【减少需要重复的开发代码量】
2017/01/19 Javascript
vue 2.0路由之路由嵌套示例详解
2017/05/08 Javascript
对于input 框限定输入值为浮点型的js代码
2017/09/25 Javascript
Vue-cli项目获取本地json文件数据的实例
2018/03/07 Javascript
Vue 开发音乐播放器之歌手页右侧快速入口功能
2018/08/08 Javascript
Vuejs+vue-router打包+Nginx配置的实例
2018/09/20 Javascript
JavaScript中this用法学习笔记
2019/03/17 Javascript
微信小程序wx.navigateTo中events属性实现页面间通信传值,数据同步
2019/07/13 Javascript
微信小程序加载机制及运行机制图解
2019/11/27 Javascript
浅谈Vuex的this.$store.commit和在Vue项目中引用公共方法
2020/07/24 Javascript
vant 自定义 van-dropdown-item的用法
2020/08/05 Javascript
python在Windows8下获取本机ip地址的方法
2015/03/14 Python
python创建和删除目录的方法
2015/04/29 Python
python开发利器之ulipad的使用实践
2017/03/16 Python
详解K-means算法在Python中的实现
2017/12/05 Python
pyqt5简介及安装方法介绍
2018/01/31 Python
详解python中的数据类型和控制流
2019/08/08 Python
pytorch加载自己的图像数据集实例
2020/07/07 Python
Mankind西班牙男士护肤品网站:购买皮肤护理、护发和剃须
2017/04/27 全球购物
广州喜创信息技术有限公司JAVA软件工程师笔试题
2012/10/17 面试题
生日派对邀请函
2014/01/13 职场文书
后勤部经理岗位职责
2014/02/23 职场文书
2014年班主任德育工作总结
2014/12/05 职场文书
领导欢迎词致辞
2015/01/23 职场文书
Element-ui Layout布局(Row和Col组件)的实现
2021/12/06 Vue.js
Redis特殊数据类型HyperLogLog基数统计算法讲解
2022/06/01 Redis