5和6的区别 thinkphp_ThinkPHP6 核心分析(五):多应用解析

这篇博客详细分析了ThinkPHP6中的多应用解析过程,包括如何通过判断'app'目录下是否有'controller'目录来确定多应用模式,以及如何根据配置文件、域名绑定和别名映射来确定应用名称。内容涵盖了Http类的构造函数、parseMultiApp方法的执行逻辑,以及与之前版本的模块对比。
摘要由CSDN通过智能技术生成

更新日志:2019-10-28 6.0正式版将多应用模式剥离出来成为一个扩展,此篇作废。

加载完中间件,接下来一步是多应用解析(ThinkPHP 6 开始支持多应用模式)。

if ($this->multi) {

$this->parseMultiApp();

}

注意到,Http类的构造函数:

public function __construct(App $app)

{

$this->app = $app;

//多应用解析,通过判断「app」目录下有无「controller」目录,没有就是多应用模式

$this->multi = is_dir($this->app->getBasePath() . 'controller') ? false : true;

}

可以看到,程序是通过判断「app」目录下有无「controller」目录来决定是否是多应用模式的。

接着看主要方法parseMultiApp:

protected function parseMultiApp(): void

{

// 虽然在「Http」的构造函数自动判断过是否开启多应用

//如果没有controller目录,$this->multi为true,就会来到本方法

// 接着还要看配置文件是否有配置

if ($this->app->config->get('app.auto_multi_app', false)) {

// 自动多应用识别

$this->bindDomain = false;

// 获取域名绑定

$bind = $this->app->config->get('app.domain_bind', []);

// 如果有域名绑定

if (!empty($bind)) {

// 获取当前子域名

$subDomain = $this->app->request->subDomain();

$domain = $this->app->request->host(true);

//完整域名绑定

if (isset($bind[$domain])) {

$appName = $bind[$domain];

$this->bindDomain = true;

//子域名绑定

} elseif (isset($bind[$subDomain])) {

$appName = $bind[$subDomain];

$this->bindDomain = true;

//二级泛域名绑定

} elseif (isset($bind['*'])) {

$appName = $bind['*'];

$this->bindDomain = true;

}

}

//如果没有域名绑定

if (!$this->bindDomain) {

//获取别名映射

$map = $this->app->config->get('app.app_map', []);

//获取禁止URL访问目录

$deny = $this->app->config->get('app.deny_app_list', []);

//获取当前请求URL的pathinfo信息(含URL后缀)

// 比如 index/index/index

$path = $this->app->request->pathinfo();

// 比如,从index/index/index获取得index

$name = current(explode('/', $path));

//解析别名映射

if (isset($map[$name])) {

//如果这个别名映射到的是一个闭包

//这样不知有啥用

if ($map[$name] instanceof Closure) {

$result = call_user_func_array($map[$name], [$this]);

$appName = $result ?: $name;

//直接取得应用名

} else {

$appName = $map[$name];

}

//$name不为空且$name在$map数组中作为KEY,或者$name是禁止URL方位的目录

} elseif ($name && (false !== array_search($name, $map) || in_array($name, $deny))) {

throw new HttpException(404, 'app not exists:' . $name);

} elseif ($name && isset($map['*'])) {

$appName = $map['*'];

} else {

$appName = $name;

}

if ($name) {

$this->app->request->setRoot('/' . $name);

$this->app->request->setPathinfo(strpos($path, '/') ? ltrim(strstr($path, '/'), '/') : '');

}

}

} else {

$appName = $this->name ?: $this->getScriptName();

}

$this->loadApp($appName ?: $this->app->config->get('app.default_app', 'index'));

}

可以看到,「pathinfo」信息的第一节会被解析成应用名称,比如index/index/index/中的index。方法的最后还调用了loadApp方法,执行的操作与前面应用的初始化类似,只是加载的文件都在该应用的目录。

跟之前的版本对比,ThinkPHP 6 貌似把原先的模块改造成了多应用,因为多应用情况下,应用名跟之前的模块名都是从pathinfo的第一节解析出来的,新的文档也没见到模块的内容了。

本作品采用《CC 协议》,转载必须注明作者和本文链接

Was mich nicht umbringt, macht mich stärker

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值