• 基于 Thinkphp 6 实现禅道路由调度


    一切的不能突破阈值,都是因为轮子造得不够。所以最好的情况大致是这样的 - 工作中出于成本和进度的考虑要,适量少造轮子,但是业余一定要多造轮子。不造出自己的轮子,永远在表层游走,没法击穿。

    个人当前阶段,最感兴趣是高效的研发管理体系和工具打造,所以研究了市面上众多产品后,还是会选择以禅道的功能体系为蓝本进行学习。因此标题所表达的内容不属于研究的主题范围,纯粹因为个人在企业级应用开发领域所涉及的一些问题的额外探索。

    禅道中的伪静态路由格式是这样的:

    /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';
        }
    }
    
    本文来源:http://www.cnblogs.com/x3d/,转载请注明。
  • 相关阅读:
    vue脚手架搭建项目
    springmvc上传下载文件
    vue双向绑定(模型变化,视图变化,反之亦然)
    android中广告轮播图总结
    studio插件
    系统图片uri的问题
    android
    mysql 外键(FOREIGN KEY)使用介绍
    不用加减乘除来做加法的题目
    Comparable接口实现和使用方法介绍
  • 原文地址:https://www.cnblogs.com/x3d/p/15115062.html
Copyright © 2020-2023  润新知