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 相关文章推荐
Smarty+QUICKFORM小小演示
Feb 25 PHP
开源SNS系统-ThinkSNS
May 18 PHP
那些年一起学习的PHP(一)
Mar 21 PHP
ajax在joomla中的原生态应用代码
Jul 19 PHP
PHP基础学习之流程控制的实现分析
Apr 28 PHP
php分页代码学习示例分享
Feb 20 PHP
PHP扩展开发入门教程
Feb 26 PHP
php编写批量生成不重复的卡号密码代码
May 14 PHP
PHP生成图像验证码的方法小结(2种方法)
Jul 18 PHP
利用switch语句进行多选一判断的实例代码
Nov 14 PHP
phpStudy配置多站点多域名方法及遇到的403错误解决方法
Oct 19 PHP
PHP迭代器和生成器用法实例分析
Sep 28 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
十大感人催泪爱情动漫 第一名至今不忍在看第二遍
2020/03/04 日漫
PHP实现格式化文件数据大小显示的方法
2015/01/03 PHP
php遍历树的常用方法汇总
2015/06/18 PHP
PHP实现文件上传和多文件上传
2015/12/24 PHP
优化WordPress中文章与评论的时间显示
2016/01/12 PHP
20个非常棒的Jquery实用工具 国外文章
2010/01/01 Javascript
Area 区域实现post提交数据的js写法
2014/04/22 Javascript
JavaScript编程的单例设计模讲解
2015/11/10 Javascript
javascript解决小数的加减乘除精度丢失的方案
2016/05/31 Javascript
js学习阶段总结(必看篇)
2016/06/16 Javascript
JS判断鼠标进入容器的方向与window.open新窗口被拦截的问题
2016/12/23 Javascript
JavaScript函数表达式详解及实例
2017/05/05 Javascript
详解webpack分包及异步加载套路
2017/06/29 Javascript
关于vue v-for 循环问题(一行显示四个,每一行的最右边那个计算属性)
2018/09/04 Javascript
详解Vue中数组和对象更改后视图不刷新的问题
2018/09/21 Javascript
iview实现select tree树形下拉框的示例代码
2018/12/21 Javascript
js事件触发操作实例分析
2019/06/21 Javascript
js实现双色球效果
2020/08/02 Javascript
Python 字典(Dictionary)操作详解
2014/03/11 Python
最近Python有点火? 给你7个学习它的理由!
2017/06/26 Python
PyQt5创建一个新窗口的实例
2019/06/20 Python
Python爬虫动态ip代理防止被封的方法
2019/07/07 Python
django 做 migrate 时 表已存在的处理方法
2019/08/31 Python
pytorch 实现将自己的图片数据处理成可以训练的图片类型
2020/01/08 Python
了解一下python内建模块collections
2020/09/07 Python
Pycharm 解决自动格式化冲突的设置操作
2021/01/15 Python
美国家居装饰店:Pier 1
2019/09/04 全球购物
将一个文本文件的内容按倒序打印出来
2015/01/05 面试题
英语专业个人求职自荐信
2013/09/21 职场文书
法制报告会主持词
2014/04/02 职场文书
《理想的风筝》教学反思
2014/04/11 职场文书
车辆转让协议书
2014/04/15 职场文书
推广活动策划方案
2014/08/23 职场文书
酒会邀请函
2015/01/31 职场文书
2019年图书室自查报告范本
2019/10/12 职场文书
GTX1650super好不好 gtx1650super显卡属于什么级别
2022/04/08 数码科技