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 相关文章推荐
PHP 读取Postgresql中的数组
Apr 14 PHP
解析PHP中ob_start()函数的用法
Jun 24 PHP
CI(CodeIgniter)框架中的增删改查操作
Jun 10 PHP
Codeigniter注册登录代码示例
Jun 12 PHP
PHP日期函数date格式化UNIX时间的方法
Mar 19 PHP
详解WordPress中调用评论模板和循环输出评论的PHP函数
Jan 05 PHP
PHP开发之用微信远程遥控服务器
Jan 25 PHP
ThinkPHP框架获取最后一次执行SQL语句及变量调试简单操作示例
Jun 13 PHP
Laravel5框架添加自定义辅助函数的方法
Aug 01 PHP
Laravel用户授权系统的使用方法示例
Sep 16 PHP
php多进程模拟并发事务产生的问题小结
Dec 07 PHP
php+ajax 文件上传代码实例
Mar 18 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
使用数据库保存session的方法
2006/10/09 PHP
PHP递归调用数组值并用其执行指定函数的方法
2015/04/01 PHP
浅谈PHP中foreach/in_array的使用
2015/11/02 PHP
关于PHP内置的字符串处理函数详解
2017/02/04 PHP
js直接编辑当前cookie的脚本
2008/09/14 Javascript
Discuz! 6.1_jQuery兼容问题
2008/09/23 Javascript
Jquery ajax不能解析json对象,报Invalid JSON错误的原因和解决方法
2010/03/27 Javascript
Javascript异步表单提交,图片上传,兼容异步模拟ajax技术
2010/05/10 Javascript
JQuery UI DatePicker中z-index默认为1的解决办法
2010/09/28 Javascript
JavaScript 变量作用域分析
2011/07/04 Javascript
超级有用的13个基于jQuery的内容滚动插件和教程
2011/07/31 Javascript
JavaScript获得url所有参数键值表的方法
2015/03/21 Javascript
js拆分字符串并将分割的数据放到数组中的方法
2015/05/06 Javascript
从零开始搭建一个react项目开发
2018/02/09 Javascript
Angularjs实现多图片上传预览功能
2018/07/18 Javascript
js中call()和apply()改变指针问题的讲解
2019/01/17 Javascript
详解微信小程序开发(项目从零开始)
2019/06/06 Javascript
vue监听dom大小改变案例
2020/07/29 Javascript
OpenLayers3实现鼠标移动显示坐标
2020/09/25 Javascript
python脚本实现查找webshell的方法
2014/07/31 Python
Python实现的质因式分解算法示例
2018/05/03 Python
对python pandas读取剪贴板内容的方法详解
2019/01/24 Python
很酷的python表白工具 你喜欢我吗
2019/04/11 Python
使用pytorch和torchtext进行文本分类的实例
2020/01/08 Python
Python 列表中的修改、添加和删除元素的实现
2020/06/11 Python
移动端html5判断是否滚动到底部并且下拉加载
2019/11/19 HTML / CSS
世界上最悠久的自行车制造商:Ribble Cycles
2017/03/18 全球购物
JD Sports瑞典:英国领先的运动时尚商店
2018/01/28 全球购物
澳洲小众品牌的集合网站:BNKR
2018/02/23 全球购物
马来西亚最热门的在线时尚商店:FashionValet
2018/11/11 全球购物
俄罗斯电子产品在线商店:UltraTrade
2020/01/30 全球购物
可以在一个PHP文件里面include另外一个PHP文件两次吗
2015/05/22 面试题
2015年人事工作总结范文
2015/04/09 职场文书
演讲比赛主持词
2015/06/29 职场文书
2016年社区国庆节活动总结
2016/04/01 职场文书
R9700摩机记
2022/04/05 无线电