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基础知识:类与对象(4) 范围解析操作符(::)
Dec 13 PHP
php 301转向实现代码
Sep 18 PHP
PHP 面向对象程序设计(oop)学习笔记(一) - 抽象类、对象接口、instanceof 和契约式编程
Jun 12 PHP
php+mysql实现数据库随机重排实例
Oct 17 PHP
PHP PDO fetch 模式各种参数的输出结果一览
Jan 07 PHP
ecshop后台编辑器替换成ueditor编辑器
Mar 03 PHP
PHP中递归的实现实例详解
Nov 14 PHP
PHP一致性hash分布式算法封装类定义与用法示例
Aug 04 PHP
PHP封装mysqli基于面向对象的mysql数据库操作类与用法示例
Feb 25 PHP
使用laravel的migrate创建数据表的方法
Sep 30 PHP
PHP实现微信提现功能(微信商城)
Nov 21 PHP
PHP程序员简单的开展服务治理架构操作详解(一)
May 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 INI配置文件的解析实现分析
2011/01/04 PHP
php实现搜索一维数组元素并删除二维数组对应元素的方法
2015/07/06 PHP
php组合排序简单实现方法
2016/10/15 PHP
PHP面向对象之领域模型+数据映射器实例(分析)
2017/06/21 PHP
PHP微信模板消息操作示例
2017/06/29 PHP
DEFER怎么用?
2006/07/01 Javascript
关于Javascript 的 prototype问题。
2007/01/03 Javascript
javascript实现unicode和字符的互相转换
2007/07/18 Javascript
js监听表单value的修改同步问题,跨浏览器支持
2009/12/31 Javascript
js URL参数的拼接方法比较
2012/02/15 Javascript
如何使用Javascript正则表达式来格式化XML内容
2013/07/04 Javascript
基于jquery实现的自动补全功能
2015/03/12 Javascript
JQuery跳出each循环的方法
2015/04/16 Javascript
基于bootstrap插件实现autocomplete自动完成表单
2016/05/07 Javascript
基于bootstrap的选择框插件icheck
2016/12/23 Javascript
页面间固定参数,通过cookie传值的实现方法
2017/05/31 Javascript
JS倒计时实例_天时分秒
2017/08/22 Javascript
vue获取验证码倒计时组件
2019/08/26 Javascript
微信小程序如何播放腾讯视频的实现
2019/09/20 Javascript
Vue修改项目启动端口号方法
2019/11/07 Javascript
vue如何搭建多页面多系统应用
2020/06/17 Javascript
vue使用better-scroll实现滑动以及左右联动
2020/06/30 Javascript
python中闭包Closure函数作为返回值的方法示例
2017/12/17 Python
python编程实现12306的一个小爬虫实例
2017/12/27 Python
使用Pycharm分段执行代码
2020/04/15 Python
linux centos 7.x 安装 python3.x 替换 python2.x的过程解析
2020/12/14 Python
Python自动化测试基础必备知识点总结
2021/02/07 Python
详解H5 活动页之移动端 REM 布局适配方法
2017/12/07 HTML / CSS
接口中的方法可以是abstract的吗
2015/07/23 面试题
回门宴父母答谢词
2014/01/26 职场文书
高三毕业寄语
2014/04/10 职场文书
居委会个人对照检查材料思想汇报
2014/09/29 职场文书
教师岗位职责范本
2015/04/02 职场文书
小学班主任工作总结2015
2015/04/07 职场文书
MySQL查看表和清空表的常用命令总结
2021/05/26 MySQL
mysql数据库隔离级别详解
2022/06/16 MySQL