ThinkPHP5源码学习篇--业务执行前的过程

了解执行过程

我们经常会好奇配置好路由、写好业务代码后,为什么在URL上输出指定内容,就是执行到业务代码呢?


App::run()

// 模块/控制器绑定
if (defined('BIND_MODULE')) {
BIND_MODULE && Route::bind(BIND_MODULE);
} elseif ($config['auto_bind_module']) {    //入口自动绑定模块 默认为false
  // 入口自动绑定
  $name = pathinfo($request->baseFile(), PATHINFO_FILENAME);
  if ($name && 'index' != $name && is_dir(APP_PATH . $name)) {
    Route::bind($name);
  }
}

如果先定义一个常量BIND_MODULE或在config.php内配置了auto_bind_module项,则调用Route::bind()对模块进行绑定

//执行逻辑程序,获取返回值
$data = self::exec($dispatch, $config);
------------------------------------------------------------
protected static function exec($dispatch, $config)
{
    switch ($dispatch['type']) {
        case 'redirect': // 重定向跳转
            //重定向,url地址将更换
            //$dispatch可以传入http://完整地址跳转到其他网站
            //也可以传入控制器+方法跳转到内部其他逻辑
            $data = Response::create($dispatch['url'], 'redirect')
                ->code($dispatch['status']);
            break;
        case 'module': // 模块/控制器/操作
            //多模块配置,执行业务逻辑
            $data = self::module(
                $dispatch['module'],    //模块信息
                $config,        //配置项
                isset($dispatch['convert']) ? $dispatch['convert'] : null
            );
            //$data 为控制器方法的返回值
            break;
        case 'controller': // 执行控制器操作
            $vars = array_merge(Request::instance()->param(), $dispatch['var']);
            //Loader::action() 执行某个控制器或当前控制器的 指定方法,此处单纯传入控制器运行有误
            //$dispatch['controller'] 1、携带模块+控制器+方法名 2、携带方法名 (前提是Request的controller被赋值)
            $data = Loader::action(
                $dispatch['controller'],
                $vars,
                $config['url_controller_layer'],
                $config['controller_suffix']
            );
            break;
        case 'method': // 回调方法
            //直接执行某个类的方法
            //$dispatch['method'] 可以是一个数组,包含类实例对象,和方法名
            //也可以是传入静态方法定义规则的字符串
            $vars = array_merge(Request::instance()->param(), $dispatch['var']);
            $data = self::invokeMethod($dispatch['method'], $vars);
            break;
        case 'function': // 闭包
            //比如在route.php 定义一个路由指向到闭包function,会执行这句
            $data = self::invokeFunction($dispatch['function']);
            break;
        case 'response': // Response 实例
            $data = $dispatch['response'];
            break;
        default:
            throw new \InvalidArgumentException('dispatch type not support');
    }
    return $data;
}

根据$dispatch数组内的type字段,来区分业务的实际执行类型
redirect:重定向跳转
module:模块控制器方法执行
controller:执行控制器操作
method:回调方法
function:闭包
response:Response实例

从个人的应用角度来说,目前用到的是module和function两种。


module模块运行

case 'module': // 模块/控制器/操作
    //多模块配置,执行业务逻辑
    $data = self::module(
        $dispatch['module'],    //模块信息
        $config,        //配置项
        isset($dispatch['convert']) ? $dispatch['convert'] : null
    );
    //$data 为控制器方法的返回值
    break;

这种是使用场景最多的,我们一般通过URL访问都是定向访问指定模块、指定控制器、指定方法运行。
$dispatch[‘module’] 包含"模块信息",这个"模块"并不单单表示框架的模块,而是路由相关的整个信息
$config是配置项
$dispatch[‘convert’]来设置传入的pathinfo信息是否自动转换

if ($config['app_multi_module']) {
    //TODO ...........
} else {
    // 单一模块部署
    $module = '';
    $request->module($module);
}

根据app_multi_module配置项来区分是否是多模块部署模式,一般来说访问地址格式是module/controller/method,在application下可以构造多个模块目录,可以在各个模块内继续生成controller等等彼此不相关的控制器。如果我们想在一个项目文件下实现多套业务逻辑,比如一个模块是api接口,一个模块是web站点,那么这将是很好的分割方式。
而如果使用单模块的模式,就没有这么复杂,application下有且有一个可被直接访问的controller结构。

那么多模块部署做了什么特殊的工作呢

/*
 * 若模块名不存在,则获取配置文件中的默认模块名
 * 如访问:http://localhost/thinkphp5/public
 * array(
 *    0 => '',
 *    1 => null,
 *    2 => null
 * */
//$result[0] 不存在则取出 配置中的default_module作为默认模块
$module    = strip_tags(strtolower($result[0] ?: $config['default_module']));
//如果请求未传入pathinfo相关信息,框架会使用default_module配置项作为默认模块

//获取绑定的模块名
$bind      = Route::getBind('module');
$available = false;

if ($bind) {
    // 绑定模块
    list($b
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值