### 2018 年 12 月 5 日 发布 ## 引言 ThinkPHP`5.2`发布测试版本以来,越来越多的的用户开始关注(让人惊奇的是居然有用户已经开始用于项目,实在是勇气可嘉^_^),并希望能有官方手册,但很遗憾的是,在正式版本尚未发布之前,官方暂时不会出开发手册。主要原因是正式发布之前,仍然有变化的可能,手册存在不确定因素,也不希望误导大家引起误会,另外一方面,确实是因为忙(带娃模式),最近连《[笨办法学ThinkPHP5.1](https://www.kancloud.cn/thinkphp/thinkphp-the-hard-way)》还一直搁浅着呢,实在是抱歉。 不过,也说过会写一些简单的教程先,让那些热衷于测试新版本的用户有机会学习和体验。因此,现在开始我会陆续更新一些`5.2`的使用教程,主要是讲述一些区别之处,避免雷区。 希望通过本系列教程抛砖引玉,开启`5.2`的学习之门,不排除可能由于后续版本的调整而产生变化,有兴趣的开发者可以参与新版文档教程的写作贡献,官方会择优收录到[ThinkPHP开发者周刊](https://www.kancloud.cn/thinkphp/weekly/content)中。 >[danger] 再次强调,`5.2`版本目前属于测试版本,存在不稳定性,请勿轻易用于正式项目。 ## 安装 由于`5.2`版本完全依赖`Composer`,因此只能通过`composer`安装才能使用,不同于`5.0`和`5.1`版本,下载或者`Git`安装都可以使用。 由于只是测试阶段,所以必须安装`dev`版本 ``` composer create-project topthink/think tp520 5.2.*-dev ``` 启动服务 ``` cd tp520 php think run ``` ## 入口文件 新版的入口文件还是位于`public`目录下面,由于直接使用`composer`的自动加载机制,因此框架核心已经不再使用`Loader`类了而是改为加载`composer`的`autoload`文件。 秉承`ThinkPHP`大道至简的原则,入口文件依然非常之简单: ``` namespace think; require __DIR__ . '/../vendor/autoload.php'; // 执行应用并响应 (new App())->run()->send(); ``` 注意每一个入口文件在新版里面总是对应一个应用,有意思的是,不同的应用入口文件除了文件名不同外代码可能完全一样(会自动绑定到文件名对应的应用)。 如果你的文件名和应用名不一致,那么可能需要略微调整如下: ``` namespace think; require __DIR__ . '/../vendor/autoload.php'; // 执行应用并响应 (new App())->name('app_name') ->run() ->send(); ``` `think\App`类还提供了很多的设置方法,都可以在`run`之前调用。这个有兴趣深入了解的可以通过源码查看。 由于新版本一个入口文件对应一个应用,如果你希望保持`5.1`版本的URL形式不变,直接访问不同的应用,一个最简单的办法就是设置`Apache`的`.htaccess`文件。 ``` <IfModule mod_rewrite.c> Options +FollowSymlinks -Multiviews RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^([a-z]+)/(.*)$ $1.php/$2 [QSA,PT,L] </IfModule> ``` 其它的WEB服务器环境可以参考修改。 ## 应用目录及命名空间调整 新版的目录结构其实看起来和`5.1`并无多大的差异,除了`thinkphp`框架目录已经纳入`vendor`之外。另外应用目录从原来的`application`更改为`app`,之所以做这个调整是为了让新手更容易理解应用的命名空间对应,不至于产生不必要的困惑。 但其实有一个本质的改变就是新版不再支持多模块,而改为原生多应用支持。因此你原来的模块目录可能在新版就变成了应用目录,为了让升级工作更简单,新版的应用命名空间和多模块保持一致。 应用命名空间类似于 ``` \app\admin\controller \app\admin\model ``` 如果你需要更改根命名空间为`top`,有两种办法。一种是修改`composer.json`文件的`autoload`,这样可以不改变目录名。 ``` "psr-4": { "top\\": "app" }, ``` 第二种办法是直接修改你的`app`目录为`top`。 无论使用哪一种方法,最后在入口文件中设置根命名空间名称。 ``` namespace think; require __DIR__ . '/../vendor/autoload.php'; // 执行应用并响应 (new App())->setRootNamespace('top') ->run() ->send(); ``` 如果你的`admin`应用不在`app`目录下面,有完全独立的命名空间例如 ``` \think\admin ``` 就可以在入口文件`admin.php`中进行指定 ``` namespace think; require __DIR__ . '/../vendor/autoload.php'; // 设置当前应用的命名空间 (new App())->setNamespace('\think\admin') ->run() ->send(); ``` 这个应用放在什么位置取决于你的命名空间自动加载路径,这一设计让你的应用可以通过`composer`来加载。 ## 多应用模式 多应用模式下面,除了应用目录的区别外,`runtime`目录下面会自动创建各个应用的子目录(注意,这个目录同样适用于`composer`加载的应用),但你只需要通过`App::getRuntimePath()`方法获取当前应用的`runtime`目录。 ``` runtime/home/ runtime/admin/ ``` 多个应用的路由定义文件都是独立的,在`route`目录下面创建对应目录的子目录存放每个应用的路由定义。 ``` route/home/ route/admin/ ``` 多个应用允许加载统一的公共文件。 ``` app/common.php app/admin/common.php app/home/common.php ``` 对于配置文件而言,`config`目录下为应用公共配置,`config`下子目录则为单个应用的独立配置。 ``` config/ config/admin/ config/home/ ``` 可能有人认为现在不同的应用是独立的入口文件,每个应用之间没法互通了,其实这个理解是错误的。不同的应用仍然是可以相互调用的,毕竟类库都是基于命名空间的。 ## 单应用模式 上面的目录结构其实是多应用设计,和之前版本一样同样支持单应用模式(之前版本其实是单一模块模式)如果你使用的是单应用的话,目录结构其实就变成了下面的结构。 ``` www ├─app 应用目录 │ ├─controller 控制器目录 │ ├─model 模型目录 │ ├─view 视图目录 │ └─ ... 更多类库目录 ``` 系统的一个默认判断单应用的规则是`app`目录下面如果存在`controller`目录,则判断当前为单应用模式。如果你更改了默认的访问控制器层的名称(或者刚好有一个应用名称也叫`controller`),那么可以在入口文件里面调用 `multi(false)`来设置为单应用模式。 ``` namespace think; require __DIR__ . '/../vendor/autoload.php'; // 执行应用并响应 (new App())->multi(false) ->run() ->send(); ``` 单应用模式下,如果需要更改命名空间,`setNamespace`和`setRootNamespace`方法是等效的。 ## 小结 本篇我们基本了解了`5.2`的目录结构和入口文件的用法,并掌握了多应用模式和单应用模式的区别及使用。下一篇,我会给大家讲下数据库和模型和之前版本的区别。