php cbd架构,CBD模式

# CBD模式

[上一页](# "上一页")[下一页](# "下一页")

ThinkPHP从3.0版本开始引入了全新的**CBD(核心Core+行为Behavior+驱动Driver)**架构模式,因为从底层开始,框架就采用核心+行为+驱动的架构体系,核心保留了最关键的部分,并在重要位置设置了标签用以标记,其他功能都采用行为扩展和驱动的方式组合,开发人员可以根据自己的需要,对某个标签位置进行行为扩展或者替换,就可以方便的定制框架底层,也可以在应用层添加自己的标签位置和添加应用行为。而标签位置类似于AOP概念中的“切面”,行为都是围绕这个“切面”来进行编程。

### Core(核心)

ThinkPHP的核心部分包括核心函数库、惯例配置、核心类库(包括基础类和内置驱动及核心行为),这些是ThinkPHP必不可少的部分。

~~~

ThinkPHP/Common/functions.php // 核心函数库

ThinkPHP/Conf/convention.php // 惯例配置文件

ThinkPHP/Conf/debug.php // 惯例调试配置文件

ThinkPHP/Mode/common.php // 普通模式定义文件

ThinkPHP/Library/Think // 核心类库包

ThinkPHP/Library/Behavior // 系统行为类库

ThinkPHP/Library/Think/App.class.php // 核心应用类

ThinkPHP/Library/Think/Behavior.class.php // 基础行为类

ThinkPHP/Library/Think/Cache.class.php // 核心缓存类

ThinkPHP/Library/Think/Controller.class.php // 基础控制器类

ThinkPHP/Library/Think/Db.class.php // 数据库操作类

ThinkPHP/Library/Think/Dispatcher.class.php // URL解析调度类

ThinkPHP/Library/Think/Exception.class.php // 系统基础异常类

ThinkPHP/Library/Think/Hook.class.php // 系统钩子类

ThinkPHP/Library/Think/Log.class.php // 系统日志记录类

ThinkPHP/Library/Think/Model.class.php // 系统基础模型类

ThinkPHP/Library/Think/Route.class.php // 系统路由类

ThinkPHP/Library/Think/Storage.class.php // 系统存储类

ThinkPHP/Library/Think/Template.class.php // 内置模板引擎类

ThinkPHP/Library/Think/Think.class.php // 系统引导类

ThinkPHP/Library/Think/View.class.php // 系统视图类

~~~

Behavior目录下面是系统内置的一些行为类库,内置驱动则分布在各个不同的驱动目录下面(参考下面的驱动部分)。

### Driver(驱动)

3.2在架构设计上更加强化了驱动的设计,替代了之前的引擎和模式扩展,并且改进了行为的设计,使得框架整体更加灵活,并且由于在需要写入数据的功能类库中都采用了驱动化的设计思想,所以使得新的框架能够轻松满足分布式部署的需求,对云平台的支持可以更简单的实现了。因此,在新版的扩展里面,已经取消了引擎扩展和模式扩展,改成配置不同的应用模式即可。

驱动包括

~~~

ThinkPHP/Library/Think/Cache/Driver // 缓存驱动类库

ThinkPHP/Library/Think/Db/Driver // 数据库驱动类库

ThinkPHP/Library/Think/Log/Driver // 日志记录驱动类库

ThinkPHP/Library/Think/Session/Driver // Session驱动类库

ThinkPHP/Library/Think/Storage/Driver // 存储驱动类库

ThinkPHP/Library/Think/Template/Driver // 第三方模板引擎驱动类库

ThinkPHP/Library/Think/Template/TagLib // 内置模板引擎标签库扩展类库

~~~

### Behavior(行为)

行为(Behavior)是ThinkPHP扩展机制中比较关键的一项扩展,行为既可以独立调用,也可以绑定到某个标签(位)中进行侦听。这里的行为指的是一个比较抽象的概念,你可以想象成在应用执行过程中的一个动作或者处理,在框架的执行流程中,各个位置都可以有行为产生,例如路由检测是一个行为,静态缓存是一个行为,用户权限检测也是行为,大到业务逻辑,小到浏览器检测、多语言检测等等都可以当做是一个行为,甚至说你希望给你的网站用户的第一次访问弹出Hello,world!这些都可以看成是一种行为,行为的存在让你无需改动框架和应用,而在外围通过扩展或者配置来改变或者增加一些功能。

而不同的行为之间也具有位置共同性,比如,有些行为的作用位置都是在应用执行前,有些行为都是在模板输出之后,我们把这些行为发生作用的位置称之为**标签(位)**,也可以称之为钩子,当应用程序运行到这个标签的时候,就会被拦截下来,统一执行相关的行为,类似于AOP编程中的“切面”的概念,给某一个标签绑定相关行为就成了一种类AOP编程的思想。

##### 系统标签位

系统核心提供的标签位置包括(按照执行顺序排列):

- app_init 应用初始化标签位

- module_check 模块检测标签位(**3.2.1版本新增**)

- path_info PATH_INFO检测标签位

- app_begin 应用开始标签位

- action_name 操作方法名标签位

- action_begin 控制器开始标签位

- view_begin 视图输出开始标签位

- view_template 视图模板解析标签位

- view_parse 视图解析标签位

- template_filter 模板解析过滤标签位

- view_filter 视图输出过滤标签位

- view_end 视图输出结束标签位

- action_end 控制器结束标签位

- app_end 应用结束标签位

在每个标签位置,可以配置多个行为,行为的执行顺序按照定义的顺序依次执行。除非前面的行为里面中断执行了(某些行为可能需要中断执行,例如检测机器人或者非法执行行为),否则会继续下一个行为的执行。

除了这些系统内置标签之外,开发人员还可以在应用中添加自己的应用标签,在任何需要拦截的位置添加如下代码即可:

~~~

tag('my_tag'); // 添加my_tag 标签侦听

// 下面的写法作用一致

\Think\Hook::listen('my_tag');

~~~

tag函数用于设置某个标签位,可以传入并且只接受一个参数,如果需要传入多个参数,请使用数组,

~~~

tag('my_tag',$params); // 添加my_tag 标签侦听

~~~

该参数为引用传值,所以只能传入变量,因此下面的传值是错误的:

~~~

tag('my_tag','param'); // 添加my_tag 标签侦听

~~~

##### 核心行为

系统的很多核心功能也是采用行为扩展组装的,对于满足项目日益纷繁复杂的需求和定制底层框架提供了更多的方便和可能性。

核心行为位于 `ThinkPHP/Behavior/` 目录下面,框架核心内置的行为包括如下:

| 行为名称 | 说明 | 对应标签位置 |

|-----|-----|-----|

| BuildLite | 生成Lite文件(3.2.1版本新增) | app_init |

| ParseTemplate | 模板文件解析,并支持第三方模板引擎驱动 | view_parse |

| ShowPageTrace | 页面Trace功能行为,完成页面Trace功能 | view_end |

| ShowRuntime | 运行时间显示行为,完成运行时间显示 | view_filter |

| TokenBuild | 令牌生成行为,完成表单令牌的自动生成 | view_filter |

| ReadHtmlCache | 读取静态缓存行为 | app_init |

| WriteHtmlCache | 生成静态缓存行为 | view_filter |

##### 行为定义

自定义的扩展行为可以放在核心或者应用目录,只要遵循命名空间的定义规则即可。行为类的命名采用:行为名称(驼峰法,首字母大写)+Behavior 行为类的定义方式如下:

~~~

namespace Home\Behavior;

use Think\Behavior;

class TestBehavior extends Behavior {

// 行为扩展的执行入口必须是run

public function run(&$params){

if(C('TEST_PARAM')) {

echo 'RUNTEST BEHAVIOR '.$params;

}

}

}

~~~

**3.2.1版本**开始,行为类的定义无需继承`Think\Behavior`类,所以,上面的定义可以简化为:

~~~

namespace Home\Behavior;

class TestBehavior {

// 行为扩展的执行入口必须是run

public function run(&$params){

if(C('TEST_PARAM')) {

echo 'RUNTEST BEHAVIOR '.$params;

}

}

}

~~~

行为类必须定义执行入口方法`run`,由于行为的调用机制影响,run方法不需要任何返回值,所有返回都通过引用返回。

> run方法的参数只允许一个,但可以传入数组。

##### 行为绑定

行为定义完成后,就需要绑定到某个标签位置才能生效,否则是不会执行的。

我们需要在应用的行为定义文件`tags.php`文件中进行行为和标签的位置定义,格式如下:

~~~

return array(

'标签名称1'=>array('行为名1','行为名2',...),

'标签名称2'=>array('行为名1','行为名2',...),

);

~~~

标签名称包括我们前面列出的系统标签和应用中自己定义的标签名称,比如你需要在app_init标签位置定义一个CheckLangBehavior行为类的话,可以使用:

~~~

return array(

'app_init'=>array('Home\Behavior\CheckLang'),

// **如果是3.2.1版本 需要改成(后面不再重复说明)**

// 'app_init'=>array('Home\Behavior\CheckLangBehavior'),

);

~~~

可以给一个标签位定义多个行为,行为的执行顺序就是定义的先后顺序,例如:

~~~

return array(

'app_init'=>array(

'Home\Behavior\CheckLang',

'Home\Behavior\CronRun'

),

);

~~~

默认情况下tags.php中定义的行为会并入系统行为一起执行,也就是说如果系统的行为定义中app_init标签中已经定义了其他行为,则会首先执行系统行为扩展中定义的行为,然后再执行项目行为中定义的行为。例如:系统行为定义文件中定义了:

~~~

'app_begin' => array(

'Behavior\ReadHtmlCache', // 读取静态缓存

),

~~~

而应用行为定义文件有定义:

~~~

'app_begin' => array(

'Home\Behavior\CheckModule',

'Home\Behavior\CheckLang',

),

~~~

则最终执行到app_begin标签(位)的时候,会依次执行:

~~~

Library\Behavior\ReadHtmlCache

Home\Behavior\CheckModule

Home\Behavior\CheckLang

~~~

三个行为(除非中间某个行为有中止执行的操作)。

如果希望应用的行为配置文件中的定义覆盖系统的行为定义,可以改为为如下方式:

~~~

'app_begin' => array(

'Home\Behavior\CheckModule',

'Home\Behavior\CheckLang',

'_overlay' => true,

),

~~~

则最终执行到app_begin标签(位)的时候,会依次执行下面两个行为:

~~~

Home\Behavior\CheckModule

Home\Behavior\CheckLang

~~~

应用行为的定义没有限制,你可以把一个行为绑定到多个标签位置执行,例如:

~~~

return array(

'app_begin'=>array('Home\Behavior\Test'), // 在app_begin 标签位添加Test行为

'app_end'=>array('Home\Behavior\Test'), // 在app_end 标签位添加Test行为

);

~~~

##### 单独执行

行为的调用不一定要放到标签才能调用,如果需要的话,我们可以在控制器中或者其他地方直接调用行为。例如,我们可以把用户权限检测封装成一个行为类,例如:

~~~

namespace Home\Behavior;

use Think\Behavior;

class AuthCheckBehavior extends Behavior {

// 行为扩展的执行入口必须是run

public function run(&$return){

if(C('USER_AUTH_ON')) {

// 进行权限认证逻辑 如果认证通过 $return = true;

// 否则用halt输出错误信息

}

}

}

~~~

定义了AuthCheck行为后,我们可以在控制器的_initialize方法中直接用下面的方式调用:

~~~

B('Home\Behavior\AuthCheck');

// 3.2.1版本中需要改成

B('Home\Behavior\AuthCheckBehavior');

~~~

[上一页](# "上一页")[下一页](# "下一页")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/301695.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPF 读取Docx文件并显示(附下载链接)

在wpf中直接显示Docx文件 ,直接看看效果吧:下面直接看代码,添加主要有两个类:DocxReader类:using System; using System.IO; using System.IO.Packaging; using System.Xml;namespace WpfEmbeddedDocx {class DocxRead…

找回创新能力 才是苹果的救命稻草

在过去的很多年里,苹果就是创新的代名词。iPod、iPhone以及iPad等,苹果的每一件产品都闪耀着巨大的创新魅力,人们可以不吃饭、不睡觉、半夜排队只为拥有一款苹果的最新产品,创新让苹果风靡世界。 但如今iPhone 5的上市&#xff0c…

php 覆盖相同键的值,php - PHP数组使用相同的字符串键组合值 - SO中文参考 - www.soinside.com...

我有以下常见问题,但无法确定哪种数组函数可能适用于以下格式:((已尝试array_merge,array_merge_recursive,array_combine,array_splice,但未按预期工作。)Array([0] > Array([r_id] > 11[r_sid] >…

李国庆离开当当,广东消委会告长隆,智能校服提供定位功能,全球首个5G火车站来了,这就是今天的大新闻...

今天是2月21日农历正月十七今天下雨 出门忘带雨伞但是心情还是美丽的因为我没被淋湿下面是今天的大新闻李国庆宣布离开一手创办的当当 (界面新闻)2月20日上午,当当联合创始人李国庆正式宣布,将离开自己一手创办并为之奋斗19年的…

Source Generators(源代码生成器)的调试器支持 | Visual Studio 2019(16.10)新功能试用...

开始之前Source Generators旨在启用编译时间元编程,即可以在编译时间创建并添加到编译中的代码。首先用一个Demo为不了解Source Generators的朋友演示一下功能。Source Generators详细说明请参看Source Generators Cookbook[1]创建一个ClassLibrary1项目&#xff08…

[收藏]REST -维基百科

表征状态转移(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。 目前在三种主流的Web服务实现方案中,因为REST模式的Web服务与复杂的SOAP和XML-RP…

程序猿专属成语 get√

全世界只有3.14 % 的人关注了数据与算法之美成语简直是中华文化底蕴一大精华,当程序员和成语联系上了,就有了下面这些火的不行的新兴成语。你还知道哪些关于程序猿的成语,欢迎留言分享。版权归原作者所有,转载仅供学习使用&#x…

哼!看你能坚持多久

21在行为心理学中,人们把一个人的新习惯或理念的形成并得以巩固至少需要21天的现象,称之为21天效应。今天一数,好巧!居然我的公众号已经连续发布了21天(本文是第22天)。仅以此文记录第21天,与大…

.NET 6 新特性 Parallel ForEachAsync

.NET 6 新特性 Parallel ForEachAsyncIntro在 .NET 6 中有一个 API Parallel.ForEachAsync 在官方的博客中一直被忽略,但是我觉得这个 API 非常的实用,类似于同步版本的 Parallel.ForEach,可以比较高效地控制多个异步任务的并行度。之前的版本…

使用remi安装php70,Linux下使用yum安装LNMP环境

如何使用yum搭建有需求的LNMP环境本人使用的是centos7系统,就以centos7的系统搭建为例Nginx安装创建/编辑文件:vi /etc/yum.repos.d/nginx.repo编辑内容:OS代表系统 OSRELEASE 代表系统版本号[nginx]namenginx repobaseurlhttp://nginx.org/p…

住宅按套内面积算,医院人脸识别黄牛,DNA碱基对可能会扩充,菜鸟发布供应链系统,猪瘟不影响食品安全,这就是今天的大新闻...

今天是2月23日农历正月十九今天的我瑟瑟发抖真想要打火锅下面是今天的大新闻住建部新规:住宅按套内面积算(中国新闻网)“住宅建筑应以套内使用面积进行交易。”住房和城乡建设部公布的一项新规征求意见稿显示,房地产交易将正式告别…

mac中的放置java类库扩展的位置

2019独角兽企业重金招聘Python工程师标准>>> /Library/Java/JavaVirtualMachines/1.6.0_35-b10-428.jdk/Contents/Home/lib/ext 转载于:https://my.oschina.net/zhangdapeng89/blog/110538

WPF实现用户头像裁剪

WPF开发者QQ群&#xff1a; 340500857 前言需要做一个用户选择头像并进行裁剪。欢迎转发、分享、点赞&#xff0c;谢谢大家~。 效果预览&#xff08;更多效果请下载源码体验&#xff09;&#xff1a;一、MainWindow.xaml代码如下&#xff1a;<Grid><Border x:Name&qu…

php5.2 zengd,大对杀狗狗再犯低级错误 ZEN狂输200目笑翻棋友

弈城围棋讯 4月29日&#xff0c;DEEPZEN仍然不知疲倦的在弈城迎战各路高手。总体来讲&#xff0c;“狗狗”战绩非常优秀&#xff0c;截止今天凌晨为止&#xff0c;它的战绩为254胜43负&#xff0c;胜率为85.5%&#xff0c;强悍的一塌糊涂&#xff0c;但是&#xff0c;“狗狗”也…

专为小机械迷而造,培养STEM思维,千万别错过!物理机械力学知识边玩边学,5岁以上请入手...

▲数据汪特别推荐点击上图进入玩酷屋自从美国前总统奥巴马先生上任后对STEM教育理念重视提升到新的层次&#xff0c;全球掀起了一波又一波的STEM教育狂潮。北上广深等中小学开设STEM课程。全国《义务教育小学科学课程标准》加强综合科技知识项目&#xff0c;将力学类科技知识学…

fusioncharts同一页面显示2个仪表盘,且以java字符串作为xml数据

为什么80%的码农都做不了架构师&#xff1f;>>> fusioncharts同一页面显示2个仪表盘&#xff0c;且以java字符串作为xml数据 <% page contentType"text/html; charsetUTF-8" %> <%String path request.getContextPath(); %> <%String x…

读书 | 一切红利最终都是趋势红利

【读书总结】| 总结/Edison Zhou在去年年底就读完了刘润老师2016年出版的《趋势红利》&#xff0c;一直没有来得及做笔记整理&#xff0c;于是&#xff0c;这就来了。1所有红利最终都是趋势红利中国的企业近年来所处的环境正在发生系统性巨变&#xff0c;企业想要成功应变&…

oracle归档日志的概念,浅谈Oracle归档日志

什么是归档日志归档日志(Archive Log)是非活动的重做日志备份.通过使用归档日志,可以保留所有重做历史记录,当数据库处于ARCHIVELOG模式并进行日志切换式,后台进程ARCH会将重做日志的内容保存到归档日志中.当数据库出现介质失败时,使用数据文件备份,归档日志和重做日志可以完全…

好强大的仿生机械,这才是真正的黑科技!

全世界只有3.14 % 的人关注了数据与算法之美仿生机械就是模仿生物的形态、结构和控制原理设计制造出的功能更集中、效率更高并具有生物特征的机械。研究仿生机械的学科称为仿生机械学&#xff0c;它是20世纪60年代末期由生物学、生物力学、医学、机械工程、控制论和电子技术等学…

windows phone 8 的新特性

2019独角兽企业重金招聘Python工程师标准>>> windows phone 8 是微软windows phone系列操作系统的一次重大升级&#xff0c;在原有的基础上添加了许多新的特性。总体看来主要八中新的特性。&#xff08;Windows phone8 缩写WP8&#xff09; <1>硬件的升级 W…