×
基础获取ThinkPHPThinkPHP环境要求ThinkPHP目录结构ThinkPHP入口文件自动生成ThinkPHP模块ThinkPHP控制器ThinkPHP开发规范配置配置格式配置加载读取配置动态配置扩展配置批量配置

架构

模块化设计URL模式多层MVCCBD模式命名空间自动加载应用模式项目编译系统流程路由路由定义规则路由正则路由静态路由闭包支持实例说明

控制器

控制器定义前置和后置操作Action参数绑定伪静态URL大小写URL生成AJAX返回跳转和重定向输入变量请求类型空操作空控制器插件控制器操作绑定到类模型模型定义模型实例化字段定义连接数据库切换数据库分布式数据库支持连贯操作WHERETABLEALIASDATAFIELDORDERLIMITPAGEGROUPHAVINGJOINUNIONDISTINCTLOCKCACHECOMMENTRELATIONUSINGfetchSqlTOKENSTRICTINDEX命名范围CURD操作数据创建数据写入数据读取数据更新数据删除ActiveRecord字段映射

查询语言

查询方式表达式查询快捷查询区间查询组合查询统计查询SQL查询动态查询子查询自动验证自动完成参数绑定虚拟模型模型分层视图模型关联模型高级模型Mongo模型视图模板定义模板主题模板赋值模板渲染获取模板地址获取内容模板引擎模板变量输出系统变量使用函数默认值输出使用运算符标签库模板继承修改定界符三元运算包含文件内置标签比较标签范围判断标签IF标签Present标签Empty标签Defined标签Volist标签Assign标签Foreach标签Define标签For标签标签嵌套Switch标签import标签使用PHP代码原样输出模板注释模板布局模板替换调试调试模式异常处理日志记录页面TraceTrace方法变量调试性能调试错误调试模型调试缓存数据缓存快速缓存查询缓存SQL解析缓存静态缓存安全输入过滤表单合法性检测表单令牌防止SQL注入目录安全文件保护模板文件上传安全防止XSS攻击其他安全建议扩展类库扩展驱动扩展缓存驱动数据库驱动日志驱动Session驱动存储驱动模板引擎驱动标签库驱动行为扩展标签扩展Widget扩展应用模式部署PATH_INFO支持URL重写模块部署域名部署入口绑定替换入口专题SESSION支持Cookie支持多语言支持数据分页文件上传验证码图像处理RESTFulRPCSAE

微信SDK

WechatIP获取和定位附录常量参考配置参考升级指导鸣谢

视图模型


视图定义

视图通常是指数据库的视图,视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。对其中所引用的基础表来说,视图的作用类似于筛选。定义视图的筛选可以来自当前或其它数据库的一个或多个表,或者其它视图。分布式查询也可用于定义使用多个异类源数据的视图。如果有几台不同的服务器分别存储组织中不同地区的数据,而您需要将这些服务器上相似结构的数据组合起来,这种方式就很有用。 视图在有些数据库下面并不被支持,但是ThinkPHP模拟实现了数据库的视图,该功能可以用于多表联合查询。非常适合解决HAS_ONEBELONGS_TO类型的关联查询。

要定义视图模型,只需要继承ThinkModelViewModel,然后设置viewFields属性即可。

例如下面的例子,我们定义了一个BlogView模型对象,其中包括了Blog模型的id、name、title和User模型的name,以及Category模型的title字段,我们通过创建BlogView模型来快速读取一个包含了User名称和类别名称的Blog记录(集)。

namespace HomeModel;
use ThinkModelViewModel;
class BlogViewModel extends ViewModel {
   public $viewFields = array(
     'Blog'=>array('id','name','title'),
     'Category'=>array('title'=>'category_name', '_on'=>'Blog.category_id=Category.id'),
     'User'=>array('name'=>'username', '_on'=>'Blog.user_id=User.id'),
   );
 }

我们来解释一下定义的格式代表了什么。

$viewFields 属性表示视图模型包含的字段,每个元素定义了某个数据表或者模型的字段。

例如:

'Blog'=>array('id','name','title');

表示BlogView视图模型要包含Blog模型中的id、name和title字段属性,这个其实很容易理解,就和数据库的视图要包含某个数据表的字段一样。而Blog相当于是给Blog模型对应的数据表定义了一个别名。

默认情况下会根据定义的名称自动获取表名,如果希望指定数据表,可以使用:

'_table'=>"test_user"
// 或者使用简化定义(自动获取表前缀)
// '_table'=>"__USER__"

如果希望给当前数据表定义另外的别名,可以使用

'_as'=>'myBlog'

BlogView视图模式除了包含Blog模型之外,还包含了Category和User模型,下面的定义:

'Category'=>array('title'=>'category_name');

和上面类似,表示BlogView视图模型还要包含Category模型的title字段,因为视图模型里面已经存在了一个title字段,所以我们通过

'title'=>'category_name'

把Category模型的title字段映射为category_name字段,如果有多个字段,可以使用同样的方式添加。

可以通过_on来给视图模型定义关联查询条件,例如:

'_on'=>'Blog.category_id=Category.id'

理解之后,User模型的定义方式同样也就很容易理解了。

Blog.categoryId=Category.id AND Blog.userId=User.id

最后,我们把视图模型的定义翻译成SQL语句就更加容易理解视图模型的原理了。假设我们不带任何其他条件查询全部的字段,那么查询的SQL语句就是

Select 
 Blog.id as id,
 Blog.name as name,
 Blog.title as title,
 Category.title as category_name,
 User.name as username 
 from think_blog Blog JOIN think_category Category JOIN think_user User 
 where Blog.category_id=Category.id AND Blog.user_id=User.id

视图模型的定义并不需要先单独定义其中的模型类,系统会默认按照系统的规则进行数据表的定位。如果Blog模型并没有定义,那么系统会自动根据当前模型的表前缀和后缀来自动获取对应的数据表。也就是说,如果我们并没有定义Blog模型类,那么上面的定义后,系统在进行视图模型的操作的时候会根据Blog这个名称和当前的表前缀设置(假设为Think_ )获取到对应的数据表可能是think_blog

ThinkPHP还可以支持视图模型的JOIN类型定义,我们可以把上面的视图定义改成:

 public $viewFields = array(
    'Blog'=>array('id','name','title','_type'=>'LEFT'),
    'Category'=>array('title'=>'category_name','_on'=>'Category.id=Blog.category_id','_type'=>'RIGHT'),
    'User'=>array('name'=>'username','_on'=>'User.id=Blog.user_id'),
   );

需要注意的是,这里的_type定义对下一个表有效,因此要注意视图模型的定义顺序。Blog模型的

'_type'=>'LEFT'

针对的是下一个模型Category而言,通过上面的定义,我们在查询的时候最终生成的SQL语句就变成:

Select 
Blog.id as id,
Blog.name as name,
Blog.title as title,
Category.title as category_name,
User.name as username 
from think_blog Blog LEFT JOIN think_category Category ON Blog.category_id=Category.id RIGHT JOIN think_user User ON Blog.user_id=User.id

我们可以在试图模型里面定义特殊的字段,例如下面的例子定义了一个统计字段

'Category'=>array('title'=>'category_name','COUNT(Blog.id)'=>'count','_on'=>'Category.id=Blog.category_id'),

视图查询

接下来,我们就可以和使用普通模型一样对视图模型进行操作了 。

$Model = D("BlogView");
$Model->field('id,name,title,category_name,username')->where('id>10')->order('id desc')->select();

看起来和普通的模型操作并没有什么大的区别,可以和使用普通模型一样进行查询。如果发现查询的结果存在重复数据,还可以使用group方法来处理。

$Model->field('id,name,title,category_name,username')->order('id desc')->group('id')->select();

我们可以看到,即使不定义视图模型,其实我们也可以通过方法来操作,但是显然非常繁琐。

$Model = D("Blog");
$Model->table('think_blog Blog,think_category Category,think_user User')
 ->field('Blog.id,Blog.name,Blog.title,Category.title as category_name,User.name as username')
 ->order('Blog.id desc')
 ->where('Blog.category_id=Category.id AND Blog.user_id=User.id')
 ->select();

而定义了视图模型之后,所有的字段会进行自动处理,添加表别名和字段别名,从而简化了原来视图的复杂查询。如果不使用视图模型,也可以用连贯操作的JOIN方法实现相同的功能。


分类导航

关注微信下载离线手册

bootwiki移动版 bootwiki
(群号:472910771)