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 相关文章推荐
Content-type 的说明
Oct 09 PHP
drupal 代码实现URL重写
May 04 PHP
PHP学习笔记 (1) 环境配置与代码调试
Jun 19 PHP
PHP把网页保存为word文件的三种方法
Apr 01 PHP
PHP实现指定字段的多维数组排序函数分享
Mar 09 PHP
php比较相似字符串的方法
Jun 05 PHP
php使用COPY函数更新配置文件的方法
Jun 18 PHP
Zend Framework实现具有基本功能的留言本(附demo源码下载)
Mar 22 PHP
php微信公众平台配置接口开发程序
Sep 22 PHP
php 自定义函数实现将数据 以excel 表格形式导出示例
Nov 13 PHP
TP5框架实现自定义分页样式的方法示例
Apr 05 PHP
php+laravel 扫码二维码签到功能
May 15 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中的phpinfo()函数
2013/06/06 PHP
探讨:如何使用PHP实现计算两个日期间隔的年、月、周、日数
2013/06/13 PHP
php抓取并保存网站图片的实现代码
2015/10/28 PHP
PHP图像裁剪缩略裁切类源码及使用方法
2016/01/07 PHP
PHP下使用mysqli的函数连接mysql出现warning: mysqli::real_connect(): (hy000/1040): ...
2016/02/14 PHP
JqGrid web打印实现代码
2011/05/31 Javascript
单击和双击事件的冲突处理示例代码
2014/04/03 Javascript
jQuery实现6位数字密码输入框
2016/12/29 Javascript
原生javascript上传图片带进度条【实例分享】
2017/04/06 Javascript
详解JS构造函数中this和return
2017/09/16 Javascript
jQuery 实现倒计时天,时,分,秒功能
2018/07/31 jQuery
VUE基于NUXT的SSR 服务端渲染
2018/11/30 Javascript
Vue 打包体积优化方案小结
2020/05/20 Javascript
小程序实现图片移动缩放效果
2020/05/26 Javascript
vue实现公告栏文字上下滚动效果的示例代码
2020/06/16 Javascript
uniapp开发小程序实现滑动页面控制元素的显示和隐藏效果
2020/12/10 Javascript
[48:00]EG vs LGD 2018国际邀请赛淘汰赛BO3 第二场 8.26
2018/08/29 DOTA
Python开发的单词频率统计工具wordsworth使用方法
2014/06/25 Python
Python中的面向对象编程详解(下)
2015/04/13 Python
Python实现选择排序
2017/06/04 Python
sublime text 3配置使用python操作方法
2017/06/11 Python
python实时监控cpu小工具
2018/06/21 Python
Python2和Python3.6环境解决共存问题
2018/11/09 Python
浅谈pycharm出现卡顿的解决方法
2018/12/03 Python
django配置app中的静态文件步骤
2020/03/27 Python
Python + selenium + crontab实现每日定时自动打卡功能
2020/03/31 Python
伦敦平价潮流珠宝首饰品牌:Astrid & Miyu
2016/10/10 全球购物
英国床垫在线:Mattress Online
2016/12/07 全球购物
英国屋顶用品和材料超市:Roofing Supplies UK
2019/08/24 全球购物
学前教育教师求职自荐信
2013/09/22 职场文书
便利店促销方案
2014/02/20 职场文书
单位法定代表人授权委托书
2014/09/20 职场文书
停车位租赁协议书
2014/09/24 职场文书
离婚协议书范文
2015/01/26 职场文书
java固定大小队列的几种实现方式详解
2021/07/15 Java/Android
Redis高并发防止秒杀超卖实战源码解决方案
2021/11/01 Redis