热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ThinkPHP框架设计及扩展详解_php实例

ThinkPHP框架是国内知名度很高应用很广泛的php框架,我们从一些简单的开发示例中来深入了解一下这个框架给我们带来的开发便捷性,以及游刃有余的扩展设计。同时也从源码分析的角度看

ThinkPHP框架是国内知名度很高应用很广泛的php框架,我们从一些简单的开发示例中来深入了解一下这个框架给我们带来的开发便捷性,以及游刃有余的扩展设计。同时也从源码分析的角度看看框架的一些不足,尽量做全面客观的评价。这里假设大家已经使用过ThinkPHP框架,基本使用方法请参考官方文档。

一、框架分层及url路由

框架的安装非常简单,下载后放入web服务器的目录即可,但是建议大家不要用默认的入口文件位置,而是放入单独的目录,便于保护代码和数据。例如我的入口文件和web服务器配置目录在web目录(外层框架里的index.php没有删除但是没有使用):

同大多数MVC框架一样,我们只需要按框架的目录结构,扩展自己的Controller和View,一些页面就开发完成了。ThinkPHP提供Module、Controller、Action三层结构来组织自己的url(3.1版本叫分组、Action和method,3.2更加国际范),目录结构如下:

这里强烈建议大家:
1、业务单独分层,不用放在Controller和Model里,例如我这里通过扩展函数库Application/Common/Common/function.php强制定义业务层名称为Service:

function service($name)
{
return D($name, 'Service');
}

好处是复用性好,假如将来要开发wap页面,写了不同的Controller,就可以复用service,假如以后的数据存储变了,比如把数据库从mysql迁移到mongodb之类,那修改Model就可以,service还是不需要任何修改。

2、基础模块和业务模块分开,不要相互引用。基础模块(例如用户基本信息)只提供数据接口没有Controller和View。
三层目录已经可以应对一般的web应用,更加复杂的web应用我们可以定义不同的入口文件加载不同的Application来解决。更更复杂的应用?门户和超大规模网站么,那就不是一个php框架能解决所有问题的了,需要自己的中间件和定制框架。

ThinkPHP的支持4种url访问模式,分别是:

1、普通模式,传统url模式,所有参数分开,例如
http://localhost/tp/index.php?m=Ucai&c=User&a=index¶=xxx
路由参数:m参数表示模块,c表示控制器,a表示访问方法
2、兼容模式
http://localhost/tp/index.php?s=/Ucai/User/index/para/xxx
路由参数通过s参数组装,当然数据参数也可以不必放在s参数里
3、pathinfo模式
http://localhost/tp/index.php/Ucai/User/index/para/xxx
这种模式把入口文件和真实脚本放在一起,含义明确,也便于SEO
4、rewrite模式
http://localhost/tp/Ucai/User/index/para/xxx
这种模式通过web服务器的rewrite配置隐藏入口文件,显得更加友好
其中pathinfo和rewrite模式需要web服务器支持。ThinkPHP有个配置需要设置为哪种模式,其实是用在U方法里生成url链接的时候用到的,访问的时候只要web服务器支持用哪种方式都可以。
也建议ThinkPHP其实不需要配置,而是记住用户访问的方式,只要第一个访问用的是哪种模式,以后生成的url都用这种方式生成,因为用户都已经访问到了就不存在支不支持的问题了。

如果正常的url不能达到我们的要求,还可以通过配置路由进一步优化url,例如我们想把url配置的更加简单
http://localhost/tp/Ucai/login/xxx
我们只需要在模块配置文件中添加如下的路由配置即可,如果用正则表达式则可以更加简化

'URL_ROUTE_RULES'   =>  array(
'login/:para' => 'Ucai/User/index',
'login' => 'Ucai/User/index',
),

到这里我们可以看到,ThinkPHP框架支持的层次结构和url配置非常丰富,能满足各种不同的需求。当然我们建议大家不要滥用路由配置,适当少量的配置能带来更好的seo效果,但是大量的配置会给项目的维护和修改带来困难。

二、ThinkPHP扩展

ThinkPHP本身含有丰富的组件和驱动,我们以数据库驱动扩展和行为扩展为例来了解一下ThinkPHP的扩展设计。

三、数据库驱动扩展

虽然ThinkPHP提供了众多的数据库驱动,但是也并不能满足所有的需求。例如我们的数据很可能不是通过直接访问数据库去实现,而是通过一些中间件(例如C程序)进行转发,从而获得更好的性能,这时就需要扩展数据库驱动来支持。
扩展非常简单,在DB/Driver目录下新建自己的驱动,例如Custom.php,然后实现request和execute方法扩展就算完成了,然后再配置文件里配置DB_TYPE=’custom’,就可以使用了。这里的request表示查询,execute表示更改数据,所有其他操作都会在Model里进行解析,包装成sql语句调用这两个方法执行。
例如我所实现的最简单的query方式,通过shell命令调用sqlite执行sql语句:

public function query($str) {
$cmd = sprintf('sqlite3 %s "%s"', $this->config['params']['dbfile'本文来源gao@daima#com搞(%代@#码@网&搞gaodaima代码], $str);
exec($cmd, $arr);
}

当然这个只是示例,ThinkPHP本身就支持sqlite3,通过pdo的方式去连接就可以。实际的应用环境可能是通过连接4层协议访问中间层端口获取数据。

四、Behavior行为扩展

Behavior行为设计是ThinkPHP框架的核心,通过行为配置和扩展,为系统的伸缩性和定制性提供了最大的支持。
假如我们要加入登录验证的功能,按照常规我们会设计自己的父类Controller,然后所有其他的Controller都从这里继承。但有了Behavior会变得更加简单和灵活,我们只需要在tags.php(没有的话在配置目录新建)添加一个Behavior就可以了:

return array(
'action_begin' => array('Ucai\Behavior\AuthBehavior'),
'view_begin' => array('Ucai\Behavior\OutputBehavior'),
);

程序在执行到action_begin流程时就会调用这个Behavior,我们可以根据状态进行跳转或终止执行。

namespace Ucai\Behavior;
class AuthBehavior {
// 行为扩展的执行入口必须是run
public function run(&$return) {
//不需要验证的action设置为true
if (!$return['AUTH_PUBLIC']) {
if (service('User')->checkLogin())
{
$return = true;
}
else
{
header('Content-Type: text/html; charset=utf-8');
redirect(U('User/index', array('url' => $_SERVER['HTTP_REFERER'])), 5, '需要登录,5秒后跳转。。。');
}
}
}
}

对于不需要登录的页面我们可以在Controller里添加配置,所有不配置的都会要求登录验证。

public $cOnfig= array('AUTH_PUBLIC' => true);

这里大家对继承和Behavior实现登录验证做一个对比,可能觉得区别不大。但是在一个复杂的项目里,这种功能会非常多,如果每个功能都放到父类里,就会非常庞大,并且部分子类可能又不需要,这时候用Behavior去定制流程就会显得游刃有余。
在上面的配置中我们还发现了一个配置OutputBehavior更能说明问题,大家有没有猜到,这个Behavior我是用来在view里输出一些共有变量,例如jscss的域名和路径等。在没有Behavior之前,大家是不是需要一个公共方法,然后每个页面都去调用一次,或者改写View的类代码?有了Behavior就显得方便许多。

namespace Ucai\Behavior;
class OutputBehavior {
public function run(&$return) {
$view = \Think\Think::instance('Think\View');
$view->assign('STATIC_URL', 'http://p3.ucai.cn/static');
}
}

扩展总结:通过Behavior扩展和数据库驱动扩展大家可以看到,ThinkPHP提供了很灵活的扩展和增强机制,能满足众多需求。其他存储、缓存、日志、模板引擎等如果需要也能很方便的扩展。

五、源码分析与不足

首先我们来分析一下框架执行的大致流程:
index.php(入口、调试模式、应用路径)
–> ThinkPHP.php(定义路径与访问模式)
–> Think\Think(类加载器、异常处理、读取共有配置)
–> Think\App(请求url调度解析、执行调度解析结果)
–> exec 执行用户定义的Controller的Action方法
–> Think\Dispatcher(根据url模式解析M、C、A和参数,加载模块配置)
–> Think\Controller(调用视图、包装和重定向)
可以看到,框架的内部流程其实比较简单,还有2个很重要的类:
Think\Hook: 监听App、Action、View的各个阶段,执行Behavior
Think\Behavior: 可配置(配置文件)可增删(代码)

在分析源代码的过程中,我们也看到了一些不足:

1、宏定义过多,难于维护和修改
建议:只在个别文件定义极少数几个宏,其余用类常量包装
2、面向过程代码过多,封装不清晰
建议:用面向对象思想包装
例如:url的解析和包装,现在是在Dispatcher里生成APP宏,然后在U方法里读取宏并生成最终url。其实完全可以定义一个类来包装例如UrlHelper,而类的二个方法parse和generate分别负责解析和生成url,这样代码结构会清晰很多。
3、有的函数和类代码封装过多,复用和改进不方便
建议:用组合来封装独立功能内容
例如:Model的校验功能,完全可以独立成类,也可以用于非Model对象调用。而现在的校验接口是Model的保护性方法,只能在Model的create函数调用,外面必须通过create方法才能校验。
4、代码规范和风格问题
希望代码风格能更加规范和标准,例如DB类作为模板方法的父类,应该用抽象方法或抛出异常形式定义所有Model需用到的方法。事实上有些方法子类是不需要的,而Db类却没有实现。

六、总结

ThinkPHP作为国内热门的php框架,确实给我们的开发带来了便利。框架开发者对web流程理解的很透彻,对php的函数应用炉火纯青。框架定义了灵活的配置和扩展适应各种需求,提供了丰富的组件和模块来加速开发。最后说一点,ThinkPHP的文档和社区支持非常完善,这也是框架流行不可缺少的重要一环。我们也希望ThinkPHP以后能更加完善自身的结构,打造成最优秀的php框架。



推荐阅读
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • PHP设置MySQL字符集的方法及使用mysqli_set_charset函数
    本文介绍了PHP设置MySQL字符集的方法,详细介绍了使用mysqli_set_charset函数来规定与数据库服务器进行数据传送时要使用的字符集。通过示例代码演示了如何设置默认客户端字符集。 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 在springmvc框架中,前台ajax调用方法,对图片批量下载,如何弹出提示保存位置选框?Controller方法 ... [详细]
  • MVC设计模式的介绍和演化过程
    本文介绍了MVC设计模式的基本概念和原理,以及在实际项目中的演化过程。通过分离视图、模型和控制器,实现了代码的解耦和重用,提高了项目的可维护性和可扩展性。详细讲解了分离视图、分离模型和分离控制器的具体步骤和规则,以及它们在项目中的应用。同时,还介绍了基础模型的封装和控制器的命名规则。该文章适合对MVC设计模式感兴趣的读者阅读和学习。 ... [详细]
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • Todayatworksomeonetriedtoconvincemethat:今天在工作中有人试图说服我:{$obj->getTableInfo()}isfine ... [详细]
  • 本文介绍了ASP.NET Core MVC的入门及基础使用教程,根据微软的文档学习,建议阅读英文文档以便更好理解,微软的工具化使用方便且开发速度快。通过vs2017新建项目,可以创建一个基础的ASP.NET网站,也可以实现动态网站开发。ASP.NET MVC框架及其工具简化了开发过程,包括建立业务的数据模型和控制器等步骤。 ... [详细]
  • SpringMVC工作流程概述
    SpringMVC工作流程概述 ... [详细]
  • 本文介绍了在Hibernate配置lazy=false时无法加载数据的问题,通过采用OpenSessionInView模式和修改数据库服务器版本解决了该问题。详细描述了问题的出现和解决过程,包括运行环境和数据库的配置信息。 ... [详细]
author-avatar
hustjs
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有