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 相关文章推荐
一键删除顽固的空文件夹 软件下载
Jan 26 PHP
PHP 第二节 数据类型之字符串类型
Apr 28 PHP
用php简单实现加减乘除计算器
Jan 06 PHP
php页码形式分页函数支持静态化地址及ajax分页
Mar 28 PHP
php验证码的制作思路和实现方法
Nov 12 PHP
Android App中DrawerLayout抽屉效果的菜单编写实例
Mar 21 PHP
浅析php如何实现App常用的秒发功能
Aug 03 PHP
cakephp2.X多表联合查询join及使用分页查询的方法
Feb 23 PHP
基于ThinkPHP5.0实现图片上传插件
Sep 25 PHP
浅析PHP数据导出知识点
Feb 17 PHP
PHP PDOStatement::getColumnMeta讲解
Feb 01 PHP
浅谈laravel中的关联查询with的问题
Oct 10 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运行提示:Fatal error Allowed memory size内存不足的解决方法
2014/12/17 PHP
YII2自动登录Cookie总是失效的解决方法
2017/06/28 PHP
thinkphp 框架数据库切换实现方法分析
2020/05/18 PHP
javascript window.opener的用法分析
2010/04/07 Javascript
js实现GridView单选效果自动设置交替行、选中行、鼠标移动行背景色
2010/05/27 Javascript
Js组件的一些写法
2010/09/10 Javascript
教你如何在 Javascript 文件里使用 .Net MVC Razor 语法
2014/07/23 Javascript
jquery滚动加载数据的方法
2015/03/09 Javascript
jQuery插件jquery-barcode实现条码打印的方法
2015/11/25 Javascript
jQuery学习笔记之入门
2016/12/14 Javascript
微信小程序 使用腾讯地图SDK详解及实现步骤
2017/02/28 Javascript
在vue中使用Autoprefixed的方法
2018/07/27 Javascript
函数式编程入门实践(一)
2019/04/20 Javascript
在Chrome DevTools中调试JavaScript的实现
2020/04/07 Javascript
Antd的table组件表格的序号自增操作
2020/10/27 Javascript
用Python代码来解图片迷宫的方法整理
2015/04/02 Python
Python中的高级函数map/reduce使用实例
2015/04/13 Python
python获取指定目录下所有文件名列表的方法
2015/05/20 Python
python爬虫获取淘宝天猫商品详细参数
2020/06/23 Python
详谈python中冒号与逗号的区别
2018/04/18 Python
Python pyinotify模块实现对文档的实时监控功能方法
2018/10/13 Python
Python面向对象之类和实例用法分析
2019/06/08 Python
如何在sublime编辑器中安装python
2020/05/20 Python
HTML5表格_动力节点Java学院整理
2017/07/11 HTML / CSS
Html5 video标签视频的最佳实践
2020/02/26 HTML / CSS
美国专注于健康商品的网站:eVitamins
2017/01/23 全球购物
介绍JAVA 中的Collection FrameWork(及如何写自己的数据结构)
2014/10/31 面试题
导游的职业规划书范文
2013/12/27 职场文书
一年级语文教学反思
2014/02/13 职场文书
护理人员的自我评价分享
2014/03/15 职场文书
企业党员一句话承诺
2014/05/30 职场文书
集体生日活动方案
2014/08/18 职场文书
环卫工人节活动总结
2014/08/29 职场文书
Nginx域名转发使用场景代码实例
2021/03/31 Servers
python 破解加密zip文件的密码
2021/04/22 Python
redis 查看所有的key方式
2021/05/07 Redis