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 强制下载文件代码
Oct 24 PHP
php入门学习知识点三 PHP上传
Jul 14 PHP
php数组函数序列之each() - 获取数组当前内部指针所指向元素的键名和键值,并将指针移到下一位
Oct 31 PHP
PHP支持多种格式图片上传(支持jpg、png、gif)
Nov 03 PHP
PHP迭代器的内部执行过程详解
Nov 12 PHP
PHP采集类Snoopy抓取图片实例
Jun 19 PHP
php ci 获取表单中多个同名input元素值的代码
Mar 25 PHP
PHP操作FTP类 (上传、下载、移动、创建等)
Mar 31 PHP
Linux php 中文乱码的快速解决方法
May 13 PHP
thinkphp5框架调用其它控制器方法 实现自定义跳转界面功能示例
Jul 03 PHP
laravel 解决paginate查询多个字段报错的问题
Oct 22 PHP
php使用redis的有序集合zset实现延迟队列应用示例
Feb 20 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/08/21 无线电
php验证session无效的解决方法
2014/11/04 PHP
Thinkphp批量更新数据的方法汇总
2016/06/29 PHP
thinkPHP多表查询及分页功能实现方法示例
2017/07/03 PHP
JS与框架页的操作代码
2010/01/17 Javascript
jquery的ajaxSubmit()异步上传图片并保存表单数据演示代码
2013/06/04 Javascript
让js弹出窗口居前显示的实现方法
2013/07/10 Javascript
利用window.name实现windowStorage代码分享
2014/01/02 Javascript
js动态创建上传表单通过iframe模拟Ajax实现无刷新
2014/02/20 Javascript
用js将内容复制到剪贴板兼容浏览器
2014/03/18 Javascript
javascript常用方法汇总
2014/12/02 Javascript
通过bootstrap全面学习less
2016/11/09 Javascript
解决vue的变量在settimeout内部效果失效的问题
2018/08/30 Javascript
详解关于element级联选择器数据回显问题
2019/02/20 Javascript
NodeJS有难度的面试题(能答对几个)
2019/10/09 NodeJs
详细介绍解决vue和jsp结合的方法
2020/02/06 Javascript
vue+axios全局添加请求头和参数操作
2020/07/24 Javascript
[00:32]DOTA2上海特级锦标赛 COL战队宣传片
2016/03/04 DOTA
[01:03:59]2018DOTA2亚洲邀请赛3月30日 小组赛B组VGJ.T VS Secret
2018/03/31 DOTA
Python深入学习之装饰器
2014/08/31 Python
浅谈python的深浅拷贝以及fromkeys的用法
2019/03/08 Python
简单了解Django ContentType内置组件
2019/07/23 Python
TENSORFLOW变量作用域(VARIABLE SCOPE)
2020/01/10 Python
win10安装python3.6的常见问题
2020/07/01 Python
使用Python项目生成所有依赖包的清单方式
2020/07/13 Python
Python实现钉钉/企业微信自动打卡的示例代码
2021/02/02 Python
传统HTML页面实现模块化加载的方法
2018/10/15 HTML / CSS
Amaze UI 文件选择域的示例代码
2020/08/26 HTML / CSS
全球知名旅游社区法国站点:TripAdvisor法国
2016/08/03 全球购物
linux下进程间通信的方式
2013/01/23 面试题
硕士研究生求职自荐信范文
2014/03/11 职场文书
拾金不昧锦旗标语
2014/06/27 职场文书
党组织领导班子整改方案
2014/10/25 职场文书
春节慰问信范文
2015/02/15 职场文书
幼儿园大班个人总结
2015/02/28 职场文书
游戏《东方异文石:爱亚利亚黎明》正式版发布
2022/04/03 其他游戏