一切的不能突破阈值,都是因为轮子造得不够。所以最好的情况大致是这样的 - 工作中出于成本和进度的考虑要,适量少造轮子,但是业余一定要多造轮子。不造出自己的轮子,永远在表层游走,没法击穿。
个人当前阶段,最感兴趣是高效的研发管理体系和工具打造,所以研究了市面上众多产品后,还是会选择以禅道的功能体系为蓝本进行学习。因此标题所表达的内容不属于研究的主题范围,纯粹因为个人在企业级应用开发领域所涉及的一些问题的额外探索。
禅道中的伪静态路由格式是这样的:
/product-browse-27.html
/product-browse-27-0-allstory-0-story.html
即除了控制器和动作,后面的参数部分,是不带参数名的,框架需要将这些参数按顺序赋值给参数。看起来会比较简洁,有一定的吸引力。因此针对这一项特性解构出来独立实现。
PHP这个玩意虽然一直在快速发展,但是似乎关注的人和应用的空间越来越少。支持国产,因此尝试在 ThinkPHP 上来研究这个问题。
tp的路由机制当前有了比较大的灵活度,由于这项特性需要使用反射机制读取方法的参数定义,因此使用 路由到调度对象(V6.0.3+)这些特性。
// 路由到自定义调度对象
Route::get('blog/:id',app
outeBlogDispatch::class);
路由调度类 app outeentaoDispatch
<?php
namespace app
oute;
use ReflectionMethod;
use thinkfacadeRoute;
class ZentaoDispatch extends hink
outedispatchUrl
{
const CTRL_KEY = '_control';
const ACT_KEY = '_action';
const PARAM_KEY = '_params';
const SEPR_KEY = '_sepr';
const SEPR = '-';
public static function rule()
{
$rule = vsprintf("<%s>-<%s><%s?><%s?>", [
self::CTRL_KEY,
self::ACT_KEY,
self::SEPR_KEY,
self::PARAM_KEY
]);
return $rule;
}
public static function addRouteRule()
{
Route::rule(ZentaoDispatch::rule(), ZentaoDispatch::class)->pattern([
self::SEPR_KEY => self::SEPR,
self::PARAM_KEY => '[w|-]+',
])->ext('html|json');
}
/**
* 解析URL地址,看该方法的主要目的是解析出控制器和动作 将第一截参数的-换为/应该就可以
* @access protected
* @param string $url URL app
outeentaoDispatch 没有意义了
* @return array
*/
protected function parseUrl(string $url): array
{
$pathinfo = $this->buildPathinfo();
$this->request->setPathinfo($pathinfo);
$route = parent::parseUrl($pathinfo);
return $route;
}
protected function buildPathinfo()
{
$pathinfo_depr = $this->rule->config('pathinfo_depr');
$vars = $this->rule->getVars();
$paths = [
$vars[self::CTRL_KEY] => $vars[self::ACT_KEY],
self::SEPR_KEY => $vars[self::SEPR_KEY],
self::PARAM_KEY => $vars[self::PARAM_KEY],
];
$pathinfo = '';
foreach ($paths as $key => $path) {
$pathinfo .= $pathinfo_depr . $key . $pathinfo_depr . $path;
}
$pathinfo = trim($pathinfo, '/');
return $pathinfo;
}
/**
* 似乎这里是最佳时机,不必重复初始化控制器对象造成性能损失
*
* @param string $name
* @return mixed|object
*/
public function controller(string $name)
{
$instance = parent::controller($name);
// 获取当前操作名
$suffix = $this->rule->config('action_suffix');
$action = $this->actionName . $suffix;
$paramValue = $this->request->param(self::PARAM_KEY);
$items = explode(self::SEPR, $paramValue);
$reflect = new ReflectionMethod($instance, $action);
$i = 0;
$params = [];
foreach($reflect->getParameters() as $param) {
if (isset($items[$i])) {
$params[$param->getName()] = $items[$i];
}
$i ++;
}
$requestReflect = new ReflectionClass($this->request);
$paramProperty = $requestReflect->getProperty('param');
$paramProperty->setAccessible(true);
$params = array_merge($this->request->param(), $params);
$paramProperty->setValue($this->request, $params);
return $instance;
}
}
注册路由
route/app.php
use app
outeentaoDispatch;
ZentaoDispatch::addRouteRule();
测试
路由:/index.php/Abc-do1-27-0-allstory-0-story.json
文件:app/controller/AbcController.php
<?php
namespace appcontroller;
class AbcController
{
public function do1($p1, $p2, $p3, $p4, $p5, $p6 = '')
{
var_dump(func_get_args());
echo 'here do1';
}
}