[TOC]
## 介绍
FastAdmin 是一款基于 ThinkPHP5 和 Bootstrap 的极速后台开发框架。
后端使用 ThinkPHP5(原生 ThinkPHP 框架),前端使用 AdminLTE 模板,做了大量二次开发和整合。
* 支持无限级父子级权限继承,父级的管理员可任意增删改子级管理员及权限设置
* 支持单管理员多角色
* 一键生成CRUD,包括控制器、模型、视图、JS、语言包、菜单等
* 一键生成控制器菜单和规则
* 一键生成API接口文档
## 插件路由演示
ThinkPHP 的路由就像是整个应用的调度室,让你的应用 url 更友好,而且让应用更安全,不会让真实的地址暴露出去。
了解过 Laravel 的同学都知道,Laravel 一开始就是一堆繁琐的路由定义,但是 ThinkPHP5 不用,系统默认已经定义了路由规则。
而 FastAdmin 更是将 ThinkPHP5 发挥到了极致,将 ThinkPHP 强大的路由功能带到了插件中,可以在后台自定义插件的路由。
这里以 CMS 插件为例[^1],在插件管理的 CMS 插件配置中看到 CMS 的插件伪静态就是利用了 ThinkPHP5 的路由功能实现,当打开 cms前台[^2] 时就是自动进入 addons/cms/index/index,下面我们分析一下是如何实现的。
![1544101918545](https://box.kancloud.cn/d9968d7fc682d1a6847a97e4bee9423e_559x515.png)
## 插件路由分析
当插件配置提交后通过 `\fastadmin\vendor\karsonzhang\fastadmin-addons\src\addons\Service.php` 中的 ` refresh() ` 将路由规则写入到 `application\extra\addons.php` 中。
```php
$file = APP_PATH . 'extra' . DS . 'addons.php';
$config = get_addon_autoload_config(true);
if ($config['autoload'])
return;
if (!is_really_writable($file)) {
throw new Exception("addons.php文件没有写入权限");
}
if ($handle = fopen($file, 'w')) {
fwrite($handle, "<?php\n\n" . "return " . var_export($config, TRUE) . ";");
fclose($handle);
} else {
throw new Exception("文件没有写入权限");
}
return true;
```
在 `addons.php` 我们可以看到真实的路由规则。
```php
array (
'/$' => 'cms/index/index',
'/cms/a/[:diyname]' => 'cms/archives/index',
'/cms/t/[:name]' => 'cms/tags/index',
'/cms/p/[:diyname]' => 'cms/page/index',
'/cms/s' => 'cms/search/index',
'/cms/c/[:diyname]' => 'cms/channel/index',
'/cms/d/[:diyname]' => 'cms/diyform/index',
),
```
当打开前台时加载 `addons.php` 中的路由配置 [^4] ,通过 `vendor\karsonzhang\fastadmin-addons\src\common.php` 注册路由。
```php
//注册路由
$routeArr = (array)Config::get('addons.route');
$domains = [];
$rules = [];
$execute = "\\think\\addons\\Route@execute?addon=%s&controller=%s&action=%s";
```
并通过 `vendor\karsonzhang\fastadmin-addons\src\addons\Route.php` 解析到插件。
```php
/**
* 插件执行
*/
public function execute($addon = null, $controller = null, $action = null)
{
$request = Request::instance();
// 是否自动转换控制器和操作名
$convert = Config::get('url_convert');
$filter = $convert ? 'strtolower' : 'trim';
$addon = $addon ? trim(call_user_func($filter, $addon)) : '';
$controller = $controller ? trim(call_user_func($filter, $controller)) : 'index';
$action = $action ? trim(call_user_func($filter, $action)) : 'index';
Hook::listen('addon_begin', $request);
if (!empty($addon) && !empty($controller) && !empty($action)) {
$info = get_addon_info($addon);
if (!$info) {
throw new HttpException(404, __('addon %s not found', $addon));
}
if (!$info['state']) {
throw new HttpException(500, __('addon %s is disabled', $addon));
}
$dispatch = $request->dispatch();
if (isset($dispatch['var']) && $dispatch['var']) {
//$request->route($dispatch['var']);
}
// 设置当前请求的控制器、操作
$request->controller($controller)->action($action);
// 监听addon_module_init
Hook::listen('addon_module_init', $request);
// 兼容旧版本行为,即将移除,不建议使用
Hook::listen('addons_init', $request);
$class = get_addon_class($addon, 'controller', $controller);
if (!$class) {
throw new HttpException(404, __('addon controller %s not found', Loader::parseName($controller, 1)));
}
$instance = new $class($request);
$vars = [];
if (is_callable([$instance, $action])) {
// 执行操作方法
$call = [$instance, $action];
} elseif (is_callable([$instance, '_empty'])) {
// 空操作
$call = [$instance, '_empty'];
$vars = [$action];
} else {
// 操作不存在
throw new HttpException(404, __('addon action %s not found', get_class($instance) . '->' . $action . '()'));
}
Hook::listen('addon_action_begin', $call);
return call_user_func_array($call, $vars);
} else {
abort(500, lang('addon can not be empty'));
}
}
```
从而使用路由功能达到插件伪静态的效果。
## 总结
* ThinkPHP5 的路由非常强大,不仅支持路由到控制器的方法,还可以路由类或者闭合。
* ThinkPHP5.0 的路由需要在 `application/config.php` 将 `url_route_on` 设置为 `true` 开启,ThinkPHP5.1 路由默认就是开启,且不能关闭。 [^3]
* 在使用使用路由时文件不一定是 `route.php`,FastAdmin 的插件路由就是单独的文件配置。
* 路由执行过程有三个部分:路由注册、路由检查和路由解析。
## 文档版本
记录文档版本更新历史
| Version | Remark | Commits By | Date |
| ------- | -------------------------- | ------------------------------------ | ---------------- |
| V1 | 初版 | [F4NNIU](mailto:sparkamax@gmail.com) | 2018-12-07 09:05 |
| V2 | 加入 TOC 和 文档和版本说明 | [F4NNIU](mailto:sparkamax@gmail.com) | 2018-12-07 23:31 |
| V3 | 加入文档版本的提交者 | [F4NNIU](mailto:sparkamax@gmail.com) | 2018-12-08 11:49 |
## 参考
文档中引用的参考
[^1]: CMS 插件 DEMO 插件管理页 https://demo.fastadmin.net/admin/addon?ref=addtabs
[^2]: CMS 前台 DEMO https://demo.fastadmin.net/cms
[^3]: ThinkPHP5路由完全指南 https://www.kancloud.cn/thinkphp/route-master/223110
[^4]: 扩展配置文件直接放入`application/extra`目录会自动加载 https://www.kancloud.cn/manual/thinkphp5/118024