1

自定义ThinkPHP的Action文件夹

Posted in PHP at 九月 9th, 2010 / 1 Comment »

最近有几个项目是基于同一个项目衍生而来的,其中大部分代码是可以公用的。考虑到后期维护的方便,准备将这些代码都整合到一起。基本设想是这样的:以ThinkPHP为框架,公用部分的代码放到/APP/Lib/Model、/APP/Lib/Common中,不同的部分放在Action中,通过配置文件定义不同项目的Action文件夹。这样,只需要能做到自定义Action文件夹的位置就算是可以了。

研究了一下,主要需要修改改两个文件:
1. /ThinkPHP/Lib/Think/Core/App.class.php
2. /ThinkPHP/Common/functions.php
ThinkPHP接收到一个URL请求后,通过文件1中的exec()操作来创建相应的控制器。文件1中的exec()主要是调用文件2中的A()函数来创建控制器的。

修改后的代码如下:
1. /ThinkPHP/Lib/Think/Core/App.class.php

    static public function exec()
    {
        // 是否开启标签扩展
        $tagOn   =  C('APP_PLUGIN_ON');
        // 项目运行标签
        if($tagOn)  tag('app_run');

        //创建Action控制器实例
        $group =  defined('GROUP_NAME') ? GROUP_NAME.C('APP_GROUP_DEPR') : '';
        if(C('ACTION_CUSTOM_DIR')){

            // C('ACTION_CUSTOM_DIR')为自定义Action文件夹名
            $module  =  A($group.MODULE_NAME, '@.'.C('ACTION_CUSTOM_DIR'), 'Custom');
        }else {
            $module  =  A($group.MODULE_NAME);
        }
        if(!$module) {
            // 是否存在扩展模块
            $_module = C('_modules_.'.MODULE_NAME);
            if($_module) {
                // 'module'=>array('classImportPath'[,'className'])
                import($_module[0]);
                $class = isset($_module[1])?$_module[1]:MODULE_NAME.'Action';
                $module = new $class;
            }else{
                // 是否定义Empty模块
                $module = A("Empty");
            }
            if(!$module){
                // 如果模块不存在,尝试创建/APP/Lib/BaseAction下的控制器
                $module  =  A($group.MODULE_NAME, '@.BaseAction', 'BaseAction');
                if(!$module) {
                // 模块不存在 抛出异常
                    throw_exception(L('_MODULE_NOT_EXIST_').MODULE_NAME);
                }
            }
        }

        //获取当前操作名
        $action = ACTION_NAME;
        if(strpos($action,':')) {
            // 执行操作链 最多只能有一个输出
            $actionList = explode(':',$action);
            foreach ($actionList as $action){
                $module->$action();
            }
        }else{
            if (method_exists($module,'_before_'.$action)) {
                // 执行前置操作
                call_user_func(array(&$module,'_before_'.$action));
            }
            //执行当前操作
            call_user_func(array(&$module,$action));
            if (method_exists($module,'_after_'.$action)) {
                //  执行后缀操作
                call_user_func(array(&$module,'_after_'.$action));
            }
        }
        // 项目结束标签
        if($tagOn)  tag('app_end');
        return ;
    }

2. /ThinkPHP/Common/functions.php

// 增加了一个$type参数,表示是否有自定义Action文件夹
function A($name,$app='@',$type='Action')
{
    static $_action = array();
    if(isset($_action[$app.$name]))
        return $_action[$app.$name];
    $OriClassName = $name;
    if(strpos($name,C('APP_GROUP_DEPR'))) {
        $array   =  explode(C('APP_GROUP_DEPR'),$name);
        $name = array_pop($array);
        $className =  $name.'Action';
        import($app.'.Action.'.implode('.',$array).'.'.$className);
    }elseif ($type=='Action'){
        $className =  $name.'Action';
        import($app.'.Action.'.$className);
    }elseif ($type=='Custom'){
        // 创建自定义Action文件夹'/APP/Lib/'.C('ACTION_CUSTOM_DIR')下的控制器
        $className =  $name.'Action';
        import($app.'.'.$className);
    }else {
        // 创建/APP/Lib/BaseAction下的控制器
        $className =  $name;
        import($app.$className);
    }
    if(class_exists($className)) {
        $action = new $className();
        $_action[$app.$OriClassName] = $action;
        return $action;
    }else {
        return false;
    }
}
Published in PHP
Tags:

One Response to “自定义ThinkPHP的Action文件夹”

  1. 九月 10th, 2010 at 7:50 上午 #减肥产品排行榜

    文章不错,博客也不错。

Leave a Reply

请输入算式结果(看不清请点击图片)
(必须)