## 多应用模式 默认安装好的目录结构是下面这样的。只列出了两级,并去除了现在无需关注的细节,如Readme、版权声明文件等。 ``` ├── app │   ├── AppService.php │   ├── BaseController.php │   ├── ExceptionHandle.php │   ├── Request.php │   ├── common.php │   ├── controller │   ├── event.php │   ├── middleware.php │   ├── provider.php │   └── service.php ├── config │   ├── app.php │   ├── cache.php ...... │   ├── trace.php │   └── view.php ├── extend ├── public │   ├── index.php │   ├── router.php │   └── static ├── route │   └── app.php ├── runtime ├── think ├── vendor │   ├── autoload.php ...... │   └── topthink └── view ``` 默认安装好后,是单应用模式的,常常无法满足项目需要。下面,我们要将其改造成多应用模式。一个应用系统,至少要分为前后台两个应用吧?另外,我还想有一个测试`(test)`的地方,演示的地方`(demo)`。 > 如果要使用多应用模式,需要先安装多应用模式扩展`think-multi-app`。方法如下: ``` /* 安装多应用支持 */ composer require topthink/think-multi-app /* 安装视图模板,不安装也可以, 但是需要修改`config/view.php`, 将其中的`type='Think' `改成 `type='php'` */ composer require topthink/think-view ``` 成功安装后,我们来测试一下控制器生成命令。 ## 快速生成应用 如果使用了多应用模式,可以快速生成一个应用,例如生成`index`, `demo`、`admin`、`test`应用的指令如下: ~~~ $ php think build index $ php think build demo $ php think build admin $ php think build test /* 框架已经内置了 index 应用 */ ~~~ ``` /* 创建 admin 应用下的一个 User 控制器 */ $ php think make:controller admin@User Controller:app\admin\controller\User created successfully. ``` > 以上的命令一定要在框架的根目录位置执行。 多应用模式下,记得要删除`app`目录下的`controller`目录(系统据此判断是否为多应用部署),以避免混乱。可以备份一下。`mv controller controller.org` ***** 修改 `app/admin/controller/index.php` 文件,如下。 ``` <?php declare (strict_types = 1); namespace app\admin\controller; use think\Request; class index { /** * 显示资源列表 * * @return \think\Response */ public function index() { // 添加此行 return 'admin::index'; } ...... ``` 在实际的部署中,为了安全起见,要确保只有`public`目录可以对外访问。在`mac`或者`linux`环境下面,可能还需要设置`runtime`目录权限为nobody可写。操作命令如下: ``` // 必要时设置目录权限(Linux / MacOS) chmod -R 777 <project_name>/runtime ``` 或者: ``` // 不同的Linux发行版本可能不一致,需要根据实际情况调整 chown -R nobody:nobody <project_name>/runtime chown -R www-data <project_name>/runtime ``` 下面给出了多应用部署的文件结构,不同的是 `app`目录下面没有`controller`目录,而`admin`应用下面有一个新建的`controller`目录。 ``` ├── app 应用根目录 │   ├── AppService.php │   ├── BaseController.php 默认基础控制器类 │   ├── ExceptionHandle.php 应用异常定义文件 │   ├── Request.php 应用请求对象 │   ├── admin 应用目录 │   │   └── controller 控制器目录 │   ├── common.php 公共函数文件 │   ├── event.php 全局事件定义文件 │   ├── middleware.php 全局中间件定义文件 │   ├── provider.php 服务提供定义文件 │   └── service.php ``` `BaseController.php`、`Request.php`和`ExceptionHandle.php`三个文件是系统默认提供的基础文件,位置可以随意移动,但要同步调整类的命名空间。如果不需要使用`Request.php`和`ExceptionHandle.php`文件,或者要调整类名,记得必须同步调整`provider.php`文件中的容器对象绑定。 `provider.php`服务提供定义文件只能全局定义,不支持在应用下单独定义。 ******** ## 全局配置 与`app`目录同级的`config`目录下面的文件是项目的全局配置文件,对所有应用有效。通过源码可以看到全局参数的加载过程如下。 ``` if (is_dir($configPath)) { $files = glob($configPath . '*' . $this->configExt); } foreach ($files as $file) { $this->config->load($file, pathinfo($file, PATHINFO_FILENAME)); } ``` ## 应用级配置 每个应用可以有独立的配置文件,相同的配置参数会覆盖全局配置。每个应用下面的配置文件会被默认加载。通过源码可以看到加载过程如下。 ``` $files = array_merge($files, glob($appPath . 'config' . DIRECTORY_SEPARATOR . '*' . $this->app->getConfigExt())); foreach ($files as $file) { $this->app->config->load($file, pathinfo($file, PATHINFO_FILENAME)); } ``` 如果需要加载额外的配置文件(如:子文件夹下面的配置文件),需要手动加载,方法如下。 ``` // 加载config/extra/config.php 配置文件 读取到extra \think\facade\Config::load('extra/config', 'extra'); ``` ## 配置获取 要使用`Config`类,首先需要在你的类文件中引入 ``` use think\facade\Config; ``` 读取一级配置的所有参数(每个配置文件都是独立的一级配置) ``` Config::get('app'); //或者使用助手函数 config('app'); ``` 读取单个配置参数 ``` Config::get('app.default_timezone'); //或者使用助手函数 config('app.default_timezone'); ``` 读取数组配置(理论上支持无限级配置参数读取) ``` Config::get('database.default.host'); ``` 读取全部配置(含应用级的配置文件) ``` Config::get(); ``` 判断是否存在某个设置参数: ``` echo (bool)Config::has('app.app_name'); echo (bool)Config::has('app.default_timezone'); ``` 动态修改配置参数: ``` // 支持批量设置参数 Config::set(['perpage' => 20], 'pagination'); echo Config::get('pagination.perpage'); ``` ## 获取各种目录位置 | 目录位置 | 目录说明 | 获取方法 | | --- | --- | --- | | 根目录 | 项目所在的目录,默认自动获取,可以在入口文件实例化`App`类的时候传入。 | `App::getRootPath()` | | 基础目录 | 根目录下的`app`目录 | `App::getBasePath()` | | 应用目录 | 当前应用所在的目录,如果是单应用模式则同基础目录,如果是多应用模式,则是`app`/应用子目录 | `App::getAppPath()` | | 配置目录 | 根目录下的`config`目录 | `App::getConfigPath()` | | 运行时目录 | 框架运行时的目录,单应用模式就是根目录的`runtime`目录,多应用模式为`runtime`/应用子目录 | `App::getRuntimePath()` | | 核心类库目录 | 框架核心类库的`think`目录 | `App::getThinkPath()` | 测试代码: ``` use think\facade\App; $a[] = App::getRootPath(); // myproject/ $a[] = App::getBasePath(); // myproject/app/ $a[] = App::getAppPath(); // myproject/app/admin/ $a[] = App::getConfigPath(); // myproject/config/ /* 这个要注意一下,不是`runtime`的根目录 */ $a[] = App::getRuntimePath(); // myproject/runtime/admin/ $a[] = App::getThinkPath(); // myproject/vendor/topthink/framework/src/ /* 获取当前应用的名称 */ $a[] =app('http')->getName(); print_r($a); ```