hinkPHP6.0架构设计的一大亮点就是对多应用的更好支持,如果你有基于ThinkPHP的多个项目,不想每个项目都重复安装一堆的扩展包和依赖,可以使用多应用模式来开发和部署,支持给每个应用绑定域名或者单独的入口文件。

注意6.0版本不再使用模块的概念,每个应用下直接是控制器而没有模块,但可以支持多级控制器。如果你熟悉了5.1版本的模块,相当于6.0版本的应用概念。

多应用和之前版本的多模块设计最本质的区别在于,每个应用是完全独立的,而多模块只是一个应用下面的层次划分。多应用可以完成之前多模块的工作,同时也具有多模块不能完成的工作。

为了避免混淆,新版不再支持多模块的概念,如果你需要在一个应用下面划分更多的层次,可以使用多级控制器的方式。

但不要因此歧视单应用,事实上,单应用模式无所不能,只要你熟悉多级控制器的话,而且对URL有完全的掌控。

出于核心尽可能精简考虑,默认安装后的模式是单应用模式,如果你需要支持多应用模式,需要单独安装多应用支持扩展。


composer require topthink/think-multi-app
安装后你的目录结构就可以按照多应用模式的结构进行调整,下面是一个标准的多应用目录结构。



www  WEB部署目录(或者子目录)
├─app           应用目录
│  ├─app_name           应用目录
│  │  ├─common.php      函数文件
│  │  ├─controller      控制器目录
│  │  ├─config          配置目录
│  │  ├─route           路由目录
│  │  ├─model           模型目录
│  │  ├─view            视图目录(优先)
│  │  └─ ...            更多类库目录
│  │
│  ├─common.php         全局公共函数文件
│  ├─event.php          全局事件定义文件
│  ├─ExceptionHandle.php应用异常处理类
│  ├─middleware.php     全局中间件定义文件
│  ├─provider.php       全局容器绑定定义文件
│  └─Request.php        应用请求对象类
│
├─config                全局配置目录
│  ├─app.php            应用配置
│  ├─cache.php          缓存配置
│  ├─console.php        控制台配置
│  ├─cookie.php         Cookie配置
│  ├─database.php       数据库配置
│  ├─filesystem.php     文件磁盘配置
│  ├─lang.php           多语言配置
│  ├─log.php            日志配置
│  ├─middleware.php     中间件配置
│  ├─route.php          URL和路由配置
│  ├─session.php        Session配置
│  ├─trace.php          Trace配置
│  └─view.php           视图配置
│
├─view                 视图目录
│  ├─app_name          应用视图目录
│  └─ ...   
│
├─public                WEB目录(对外访问目录)
│  ├─index.php          入口文件
│  ├─router.php         快速测试文件
│  └─.htaccess          用于apache的重写
│
├─extend                扩展类库目录
├─runtime               应用的运行时目录(可写,可定制)
├─vendor                第三方类库目录(Composer依赖库)
├─build.php             自动生成定义文件(参考)
├─composer.json         composer 定义文件
├─LICENSE.txt           授权说明文件
├─README.md             README 文件
├─think                 命令行入口文件

注意,多应用模式下,每个应用的路由定义是独立的。

多应用模式在设计的时候已经考虑到了每个应用的完全独立(甚至支持composer方式扩展应用),包括视图文件、路由定义以及配置文件都直接纳入应用目录下,只需要在应用目录下创建对应的viewrouteconfig目录即可。

快速创建应用

你可以通过指令快速创建一个应用,例如创建一个demo应用。

php think build demo
创建成功后,我们可以通过访问
http://tp.com/demo

访问应用。

应用名必须使用小写,否则在Linux环境下可能会出错。

多入口文件

允许为每个应用创建单独的入口文件访问,例如创建一个admin.php入口文件来访问admin应用,你只需要在入口文件中添加下面的代码。

// [ 应用入口文件 ]
namespace think;

require __DIR__ . '/../vendor/autoload.php';

// 执行HTTP应用并响应
$http = (new  App())->http;
$response = $http->run();
$response->send();
$http->end($response);

原则上,多应用模式下,每个应用都可以有一个独立的入口文件,例如index.php 作为前台应用入口,admin.php 作为后台应用入口。入口文件的代码基本上完全一样,系统会自动使用入口文件名作为应用名。

一个特例是,如果你要把index.php入口绑定index应用,你必须显式指定应用名,否则会自动作为自动多应用入口文件。

// [ 应用入口文件 ]
namespace think;

require __DIR__ . '/../vendor/autoload.php';

// 执行HTTP应用并响应
$http = (new  App())->http;
$response = $http->name('index')->run();
$response->send();
$http->end($response);
多入口的应用访问
规则是
http://tp.com/index.php/controllerName/actionName
http://tp.com/admin.php/controllerName/actionName
一般情况下,我们会通过URL重写把index.php入口隐藏,访问index应用通常变成
http://tp.com/controllerName/actionName
使用多个入口文件的一个好处是,你可以针对某个应用单独开启调试模式,或者在入口文件中增加额外的设置。
// [ 应用入口文件 ]
namespace think;

require __DIR__ . '/../vendor/autoload.php';

// 执行HTTP应用并响应 开启调试模式
$http = (new  App())->debug(true)->http;
$response = $http->name('index')->run();
$response->send();
$http->end($response);

自动多应用部署

如果你有超过两个应用,那么强烈建议你使用自动多应用部署,优势是使用同一个入口文件访问不同的应用,和使用多个入口文件没有本质的区别,而且URL更加优雅。

如果你的入口文件是index.php,则会默认使用自动多应用模式,应用访问地址变成(index.php入口文件已经通过URL重写隐藏)

// 访问index应用
http://tp.com/index/controllerName/actionName
// 访问admin应用
http://tp.com/admin/controllerName/actionName

自动多应用模式下,引入了路由网关的概念,你可以对URL的应用访问设置映射。

config\app.php配置文件中设置

'app_map'	=>	[
	'home'	=>	'index',
	'think'	=>	'admin',
],
这样,当我们访问
http://admin.tp.com //访问admin应用
http://blog.tp.com //访问blog应用
http://user.tp.com //访问user应用
http://a.tp.com //访问index应用

你也可以把多个域名绑定到同一个应用上,然后在该应用的路由里面定义不同的域名路由规则。总之,进入某个应用后,URL的权限就都交给路由来控制了。

多应用智能识别

前面说过,给不同的应用绑定不同的域名或者入口是简化URL地址最有效的办法,如果没有绑定入口或者域名的情况下,URL里面的应用名其实是会自动识别的,假设我们访问一个不存在的应用,例如访问:

http://tp.com/think
假设并不存在think应用,这个时候系统会自动切换到单应用模式,如果有定义全局的路由,也会进行路由匹配检查,例如我们在route/route.php全局路由中注册了think路由规则:

Route::get('think', function () {
    return 'hello,ThinkPHP!';
});
访问上面的URL就会输出
hello,ThinkPHP!

实际上是首先定位think应用是否存在,因为这里think应用不存在,所以会去匹配全局路由,如果没有匹配到全局路由的话,那么会把think当成单应用的控制器。

如果你希望think应用不存在的时候,直接访问默认应用的路由,可以在app.php中配置

// 开启应用快速访问
'app_express'    =>    true,
// 默认应用
'default_app'    =>    'home',

这个时候就会访问home应用下的think路由规则而不是全局路由规则。

其它注意事项

多应用模式下,无法监听应用的AppInitHttpRun事件,因为在多应用解析之前这两个事件已经完成分发了。如果有类似需求,应该改成应用中间件执行或者在全局事件定义文件中添加监听。

不支持单独定义应用的provider.php服务提供定义。








AD:阿里云2000元代金券九折优惠点我领取 ¥2000元大礼包

AD:腾讯云2860元无门槛代金券,限时领取点我领取 ¥2860无门槛代金券