ThinkPHP框架设计及扩展详解(2)

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: 可配置(配置文件)可增删(代码)

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

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/5d77edf19f501ddf51d36b6635d3b057.html