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 mail 通过Windows的SMTP发送邮件失败的解决方案
May 27 PHP
浅析虚拟主机服务器php fsockopen函数被禁用的解决办法
Aug 07 PHP
codeigniter教程之多文件上传使用示例
Feb 11 PHP
PHP中date与gmdate的区别及默认时区设置
May 12 PHP
php中实现记住密码下次自动登录的例子
Nov 06 PHP
php站内搜索关键词变亮的实现方法
Dec 30 PHP
THINKPHP支持YAML配置文件的设置方法
Mar 17 PHP
smarty模板引擎之配置文件数据和保留数据
Mar 30 PHP
PHP连接MSSQL方法汇总
Feb 05 PHP
PHP单例模式是什么 php实现单例模式的方法
May 14 PHP
PHP删除二维数组中相同元素及数组重复值的方法示例
May 05 PHP
Laravel使用支付宝进行支付的示例代码
Aug 16 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
php5 pdo新改动加载注意事项
2008/09/11 PHP
初学CAKEPHP 基础教程
2009/11/02 PHP
php HandlerSocket的使用
2011/05/02 PHP
php中Ctype函数用法详解
2014/12/09 PHP
WordPress导航菜单的滚动和淡入淡出效果的实现要点
2015/12/14 PHP
asp 取文本框名称代码
2008/12/02 Javascript
遨游,飞飞,IE,空中网 浏览器无提示关闭方法
2011/07/11 Javascript
jquery submit ie6下失效的原因分析及解决方法
2013/11/15 Javascript
JQuery实现绚丽的横向下拉菜单
2013/12/19 Javascript
javascript图片滑动效果实现
2021/01/28 Javascript
AugularJS从入门到实践(必看篇)
2017/07/10 Javascript
微信小程序对接七牛云存储的方法
2017/07/30 Javascript
解决IE7中使用jQuery动态操作name问题
2017/08/28 jQuery
vue-router 路由基础的详解
2017/10/17 Javascript
详解vue-router 命名路由和命名视图
2018/06/01 Javascript
vue element table 表格请求后台排序的方法
2018/09/28 Javascript
javascript实现获取中文汉字拼音首字母
2020/05/19 Javascript
Element Popover 弹出框的使用示例
2020/07/26 Javascript
javascript实现打砖块小游戏(附完整源码)
2020/09/18 Javascript
[06:21]完美世界亚洲区首席发行官竺琦TI3采访
2013/08/26 DOTA
python 执行文件时额外参数获取的实例
2018/12/18 Python
对pandas处理json数据的方法详解
2019/02/08 Python
通过代码实例了解Python3编程技巧
2020/10/13 Python
python中使用np.delete()的实例方法
2021/02/01 Python
纯css3制作煽动翅膀的蝴蝶的示例
2018/04/23 HTML / CSS
港湾网络笔试题
2014/04/19 面试题
和平主题的演讲稿
2014/01/12 职场文书
查摆问题整改措施
2014/10/24 职场文书
论文答谢词
2015/01/20 职场文书
幼儿教师师德师风自我评价
2015/03/05 职场文书
自我推荐信怎么写
2015/03/24 职场文书
监护人证明
2015/06/19 职场文书
生活委员竞选稿
2015/11/21 职场文书
python迷宫问题深度优先遍历实例
2021/06/20 Python
MySQL基础快速入门知识总结(附思维导图)
2021/09/25 MySQL
MySQL中order by的使用详情
2021/11/17 MySQL