多数大学生出来选择的工作和专业无关
首页 > 专业知识

解密ThinkPHP3.1.2版本之独立分组功能应用

时间:2018-05-16 17:38:38 [来源]:郑州PHP培训学校

   解密ThinkPHP3.1.2版本之独立分组功能应用

  ThinkPHP的分组功能是广为开发者使用的一个具有很大实用价值的功能,该功能可以解决中大型项目情况中MVC分层文件过多导致不易管理的问题。
  而ThinkPHP3.1.2版本添加的独立分组功能则为此类问题提出了新的解决思路,更加适合组件化的开发模式。我们就此了解下这一功能。
  1.概述
  独立分组功能不影响原有分组模式的运行,并且原有分组模式仅需移动目录结构即可完成独立分组模式的升级,无需任何应用代码的改动。
  而且新的独立分组可以很方便的独立装卸和移动,可以摆脱原来普通分组文件分散在各个不同的目录下面的困扰。
  独立分组的URL访问和原先的普通分组一样,没有任何区别,配置分组列表也仍然采用APP_GROUP_LIST参数配置。设置默认分组则采用DEFAULT_GROUP参数。例如:
  'APP_GROUP_LIST'=>'Home,Admin','DEFAULT_GROUP'=>'Home',虽然新的独立分组已经完全可以取代原有普通分组模式,不过为了考虑到原有分组项目的平滑升级,此次新版增加了一个配置参数:
  APP_GROUP_MODE 用于配置分组模式,默认为0 为原有的普通分组模式,如果设置为1 则表示启用独立分组模式。
  是否需要升级为独立分组模式完全由你决定,相信你看完后面的内容会有明智的选择。
  2.目录结构
  启用独立分组模式后,你需要在项目目录下面创建独立分组目录,该目录可以由项目配置文件通过APP_GROUP_PATH参数配置,默认值为Modules。假设我们没有做任何更改的话,在Modules目录下面就是每个分组的子目录,每个分组是完全独立的,包括模型、控制器、视图、配置和函数文件等等,你可以很方便的实现分组的移动和卸载。
  标准的独立分组目录结构为(以一个Home分组为例):
  ─Home Home分组目录 ├─Common 分组函数目录 ├─Conf 分组配置目录 ├─Lang 分组语言包目录 ├─Action 分组Action控制器目录 ├─Model 分组Model模型目录 ├─Widget 分组Widget目录 ├─ORG 分组扩展类库目录 ├─... 其他分层目录 └─Tpl 分组模板目录(注意:独立分组的目录结构目前需要手动创建)基本上可以看到,独立分组除了没有入口文件外,其他独立项目具备的结构都基本具备了。
  从原来的普通分组升级到独立分组,只需要在项目配置文件中增加:
  'APP_GROUP_MODE'=>1
  然后把原来项目Lib目录下面属于对应分组的MVC文件,以及分组的函数、配置和语言(如果有的话)文件依次对照上面的独立分组的目录结构放入对应目录即可。
  3.公共文件
  采用独立分组后,原来的项目Lib目录则作为分组公共类库文件设计,如果你的多个独立分组需要调用公共的Action或者Model类的话(其实还包括其他的分层控制器和模型类),则可以把这些公共类放入项目的Lib目录下面的对应目录(实际的升级过程中,这些公共类库文件基本上保持目录结构不变,所以无需移动)。
  分组的公共类库文件无需手动加载,均采用了自动加载机制。
  所以,最终采用独立分组模式的实际项目目录结构如下:
  ├─index.php   项目入口文件 ├─Common 项目公共文件目录 ├─Conf 项目配置目录 ├─Lang 项目语言目录 ├─Modules 独立分组目录 │ ├─Home Home分组目录(独立分组目录结构参考前面) │ ├─Admin Admin分组目录 │ └─... 其他分组目录 ├─Lib 分组公共类库目录 │ ├─Action 公共Action类库目录 │ ├─Behavior. 公共行为类库目录 │ ├─Model 公共模型类库目录 │ └─... 其他公共类库目录 ├─Runtime 项目运行时目录 │ ├─Cache 模板缓存目录 │ ├─Data 数据缓存目录 │ ├─Logs 日志文件目录 │ └─Temp 临时缓存目录4.模板文件
  独立分组的模板文件由项目的Tpl目录移动到了独立分组目录的Tpl目录,原来的模板分组子目录不再需要,例如:
  Tpl/Home/Index/index.html
  移动到独立分组下的Tpl目录后,应该是:
  Tpl/Index/index.html
  模板主题功能仍然支持。
  5.调用类库
  独立分组在导入类库的时候,使用方法和导入项目类库基本一致,例如:
  import('@.Action.TestAction'); // 导入当前分组下的Action/TestAction.class.php import('@.ORG.Util.Image'); // 导入当前分组下的ORG/Util/Image.class.php独立分组不考虑多个分组之间的交互和调用,只能调用公共类库。
  如果你必须调用其他分组的类库,而没有采用公共类库设计的话,那么可以使用:
  import('ORG.Util.Image',APP_PATH.'Modules/Admin');不过,采用独立分组后,A方法和R方法、D方法均不支持跨分组调用了。
 
  解密ThinkPHP3.1.2版本之模板继承
  模板继承是ThinkPHP3.1.2版本添加的一项更加灵活的模板布局方式,模板继承不同于模板布局,甚至来说,应该在模板布局的上层。模板继承其实并不难理解,就好比类的继承一样,模板也可以定义一个基础模板(或者是布局),并且其中定义相关的区块(block),然后继承(extend)该基础模板的子模板中就可以对基础模板中定义的区块进行重载。
  因此,模板继承的优势其实是设计基础模板中的区块(block)和子模板中替换这些区块。
  每个区块由标签组成,并且不支持block标签的嵌套。
  下面就是基础模板中的一个典型的区块设计(用于设计网站标题):
  <block name="title"><title>网站标题</title></block>
  block标签必须指定name属性来标识当前区块的名称,这个标识在当前模板中应该是唯一的,block标签中可以包含任何模板内容,包括其他标签和变量,例如:
  <block name="title"><title>{$web_title}</title></block>
  你甚至还可以在区块中加载外部文件:
  <block name="include"><include file="Public:header" /></block>
  一个模板中可以定义任意多个名称标识不重复的区块,例如下面定义了一个base.html基础模板:
  <html> <head> <meta. http-equiv="Content-Type" content="text/html; charset=utf-8"> <block name="title"><title>标题</title></block> </head> <body> <block name="menu">菜单</block> <block name="left">左边分栏</block> <block name="main">主内容</block> <block name="right">右边分栏</block> <block name="footer">底部</block> </body> </html>
  然后我们在子模板(其实是当前操作的入口模板)中使用继承:
  <extend name="base" /> <block name="title"><title>{$title}</title></block> <block name="menu"> <a href="/" >首页</a> <a href="/info/" >资讯</a> <a href="/bbs/" >论坛</a> </block> <block name="left"></block> <block name="content"> <volist name="list" id="vo"> <a href="/new/{$vo.id}">{$vo.title}</a><br/>{$vo.content} </volist> </block> <block name="right">
  最新资讯:
  <volist name="news" id="new"> <a href="/new/{$new.id}">{$new.title}</a><br/> </volist> </block> <block name="footer">@ThinkPHP2012 版权所有 </block>
  可以看到,子模板中使用了extend标签定义需要继承的模板,extend标签的用法和include标签一样,你也可以加载其他模板:
  <extend name="Public:base" />
  或者使用绝对文件路径加载
  <extend name="./Tpl/Public/base.html" />
  在当前子模板中,只能定义区块而不能定义其他的模板内容,否则将会直接忽略,并且只能定义基础模板中已经定义的区块。
  例如,如果采用下面的定义:
  <block name="title"><title>{$title}</title></block> <a href="/" >首页</a> <a href="/info/" >资讯</a> <a href="/bbs/" >论坛</a>
  导航部分将是无效的,不会显示在模板中。
  在子模板中,可以对基础模板中的区块进行重载定义,如果没有重新定义的话,则表示沿用基础模板中的区块定义,如果定义了一个空的区块,则表示删除基础模板中的该区块内容。
  上面的例子,我们就把left区块的内容删除了,其他的区块都进行了重载。
  子模板中的区块定义顺序是随意的,模板继承的用法关键在于基础模板如何布局和设计规划了,如果结合原来的布局功能,则会更加灵活。
 
  解密ThinkPHP3.1.2版本之模块和操作映射
  模板和操作映射功能是ThinkPHP3.1.2版本支持的对模块和操作设置的映射机制,由于可以通过改变配置动态改变(实际真正改变,并非别名)URL访问地址,加强了应用的安全性,而且,映射机制具有URL不区分大小写访问的特性,对于应用的迁移也有很大的帮助。
  因为,普通情况下,如果需要更改URL的模块或者操作访问的话,需要改动的文件较多,容易导致关联性出错。尤其是很多应用需要迁移到新版本的时候,由于模型和控制器改动较多,导致URL地址出现大的调整,通过模块和操作映射功能,就可以很轻松的解决此类问题。
  1.模块映射
  要定义模块映射,我们只需要在配置文件中定义:
  'URL_MODULE_MAP'=>array(  'user'   => 'Member',  'blog'   => 'Info', )URL_MODULE_MAP是一个数组,每个数组项表示:
  '模块映射名'=>'实际模块名'
  映射名称不区分大小写,所以设置后,URL访问从原来的:
  http://serverName/index.php/Member/indexhttp://serverName/index.php/Info/index变成了:
  http://serverName/index.php/user/indexhttp://serverName/index.php/blog/index并且原来的访问URL是失效的,这也是和定义路由方式改变URL的区别之一。没有定义映射的模块访问不变。
  定义了模块映射后,可以通过MODULE_ALIAS常量读取当前模块的URL名称。
  2.操作映射
  不仅是模块名称可以映射,操作名称也支持映射,而且是针对模块来设置的,操作映射的定义方式为:
  'URL_ACTION_MAP'=>array(  'Member'  => array(    'register' => 'add',    ),  'Info'   => array(    'list'   => 'index'    ), )URL_ACTION_MAP参数是一个二维数组,每个数组项表示:
  '实际模块名'=>array(  '操作映射名1'=>'实际操作名1'  '操作映射名2'=>'实际操作名2'  ...... )操作映射名不区分大小写,如上定义后,URL访问从http://serverName/index.php/Member/addhttp://serverName/index.php/Info/index变成了(不考虑前面定义的模块映射):
  http://serverName/index.php/Member/registerhttp://serverName/index.php/Info/list同样,原来的URL地址访问则失效。没有定义映射的操作访问地址不变。
  定义了操作映射后,可以通过ACTION_ALIAS常量读取当前操作在URL地址中的操作名。
  操作映射和模块映射可以同时定义,没有影响,例如:
  'URL_MODULE_MAP'=>array(  'user'   => 'Member', ), 'URL_ACTION_MAP'=>array(  'Member'  => array(    'register888' => 'add',    ), )则,原来的注册地址
  http://serverName/index.php/Member/add
  变成了
  http://serverName/index.php/user/register8883.U函数自动支持
  可能很多人会担心,在设置了模块和操作映射后,U函数就会出现需要随之改动的情况。其实不需要担心,因为U函数内部已经自动支持了模块和操作映射的情况。
  例如,原来在模板文件中使用了
  <a href="{:U('Member/add')}">用户注册</a>
  无论如何定义Member模块和add操作的映射,U方法的写法始终保持不变,仍然会正确的指向映射后的URL地址。
  总结:
  模块和操作映射可以用于如下场合:
  1、有经常变化URL需要的场合
  2、对URL安全性较高的场合
  3、需要移植的应用不希望改变URL地址的场合
  需要注意的事项:
  在使用了模块和操作映射后,对相关URL地址的路由定义可能需要调整。
 

上一篇:3种方法实现PHP多线程异步请求

下一篇:PHP获取真实客户端的真实IP