Webman 自动解析出来的控制器 使用路由时添加中间件无效

2337669928@qq.com

这是中间件

截图

这是使用中间件的路由 (没反应)

截图

这是使用正常方式解析 (正常)

截图


应该怎么解决 ?

1951 4 1
4个回答

walkor 打赏

问题一

里面Route::any('login', 应该改成Route::any('/login',,路由的第一个参数都要是 / 开头。

Route::group('/admin', function () {
    Route::any('/login', [\app\controller\admin\Login::class, 'index']);
})->middleware([
    \app\middleware\Tokenauth::class
]);

问题二

自动路由里已经给所有的控制器自动加了路由,所以你再次添加相同的路由会报错。如果你要手动给某些uri添加路由,就在自动路由里将其忽略,所以config/route.php里应该是类似这样的代码。

<?php
use Webman\Route;

// 自动路由忽略以下uri
$ignore_list = [
    '/admin/login',
];

$dir_iterator = new \RecursiveDirectoryIterator(app_path());
$iterator = new \RecursiveIteratorIterator($dir_iterator);
foreach ($iterator as $file) {
    // 忽略目录和非php文件
    if (is_dir($file) || $file->getExtension() != 'php') {
        continue;
    }

    $file_path = str_replace('\\', '/',$file->getPathname());
    // 文件路径里不带controller的文件忽略
    if (strpos($file_path, 'controller') === false) {
        continue;
    }

    // 根据文件路径计算uri
    $uri_path = strtolower(str_replace('controller/', '',substr(substr($file_path, strlen(app_path())), 0, -4)));
    // 根据文件路径是被类名
    $class_name = str_replace('/', '\\',substr(substr($file_path, strlen(base_path())), 0, -4));

    if (!class_exists($class_name)) {
        echo "Class $class_name not found, skip route for it\n";
        continue;
    }

    // 通过反射找到这个类的所有共有方法作为action
    $class = new ReflectionClass($class_name);
    $class_name = $class->name;
    $methods = $class->getMethods(ReflectionMethod::IS_PUBLIC);

    $route = function ($uri, $cb) use ($ignore_list) {
        if (in_array($uri, $ignore_list)) {
            return;
        }
        Route::any($uri, $cb);
        Route::any($uri.'/', $cb);
        echo "$uri " . json_encode($cb)."\n";
    };

    // 设置路由
    foreach ($methods as $item) {
        $action = $item->name;
        if (in_array($action, ['__construct', '__destruct'])) {
            continue;
        }
        // action为index时uri里末尾/index可以省略
        if ($action === 'index') {
            // controller也为index时可以uri里可以省略/index/index
            if (substr($uri_path, -6) === '/index') {
                $route(substr($uri_path, 0, -6), [$class_name, $action]);
            }
            $route($uri_path, [$class_name, $action]);
        }
        $route($uri_path.'/'.$action, [$class_name, $action]);
    }

}

// 自己的路由
Route::group('/admin', function () {
    Route::any('/login', [\app\controller\admin\Login::class, 'index']);
})->middleware([
    \app\middleware\Tokenauth::class
]);
  • 2337669928@qq.com 2022-03-06

    作者还会回答的时候 我自己写了一个方案,作者看看哪个好

2337669928@qq.com
//================路由自动反射================
$RouteGroup = [
    "/admin" => [
        app\middleware\Tokenauth::class,
    ],
];

$dir_iterator = new \RecursiveDirectoryIterator(app_path());
$iterator = new \RecursiveIteratorIterator($dir_iterator);
foreach ($iterator as $file) {
    // 忽略目录和非php文件
    if (is_dir($file) || $file->getExtension() != 'php') {
        continue;
    }
    $file_path = str_replace('\\', '/',$file->getPathname());
    // 文件路径里不带controller的文件忽略
    if (strpos($file_path, 'controller') === false) {
        continue;
    }
    // 根据文件路径计算uri
    $uri_path = strtolower(str_replace('controller/', '',substr(substr($file_path, strlen(app_path())), 0, -4)));
    // 根据文件路径是被类名
    $class_name = str_replace('/', '\\',substr(substr($file_path, strlen(base_path())), 0, -4));

    if (!class_exists($class_name)) {
        echo "Class $class_name not found, skip route for it\n";
        continue;
    }

    // 通过反射找到这个类的所有共有方法作为action
    $class = new ReflectionClass($class_name);
    $class_name = $class->name;
    $methods = $class->getMethods(ReflectionMethod::IS_PUBLIC);

    $route = function ($uri, $cb, $mid = []) {
        //echo "Route $uri [{$cb[0]}, {$cb[1]}]\n";
        if($mid != []){
            Route::any($uri, $cb)->middleware($mid);
            Route::any($uri.'/', $cb)->middleware($mid);
        }else{
            Route::any($uri, $cb);
            Route::any($uri.'/', $cb);
        }

    };

    // 设置路由
    foreach ($methods as $item) {
        $action = $item->name;
        $__Class__ = substr($uri_path,0,strpos($uri_path,'/',1));
        if (in_array($action, ['__construct', '__destruct'])) {
            continue;
        }
        // action为index时uri里末尾/index可以省略
        if ($action === 'index') {
            // controller也为index时可以uri里可以省略/index/index
            if (substr($uri_path, -6) === '/index') {
                $route(substr($uri_path, 0, -6), [$class_name, $action]);
            }
            if(array_key_exists($__Class__,$RouteGroup)){
                $route($uri_path, [$class_name, $action],$RouteGroup[$__Class__]);
            }else{
                $route($uri_path, [$class_name, $action]);
            }
        }

        if(array_key_exists($__Class__,$RouteGroup)){
            $route($uri_path.'/'.$action, [$class_name, $action],$RouteGroup[$__Class__]);
        }else{
            $route($uri_path.'/'.$action, [$class_name, $action]);
        }
    }

}
//==================================================================================
walkor 打赏

刚刚给webman加了个自动路由插件,可以用这个插件,使用更简单,不用做任何配置。如果你想定制某个路由,直接在config/route.php直接定义即可,自动路由组件会自动忽略它,使用你的自定义配置。

安装
composer require webman/auto-route

记得删除 config/route.php 里自动路由的脚本

插件文档地址 https://www.workerman.net/plugin/17

2337669928@qq.com

截图
截图
截图
截图
那个管理员 就是个相声演员。

而且我天天都在 活跃群的气氛 发布问题 引导话题的。群主可以看群聊记录 我每天都在。但是那个管理就喜欢没事找事。而且我也屏蔽他的

  • walkor 2022-03-07

    截图
    这个回复没看出哪里装逼哈。再说谁还没装过,我之前也装,但是不代表不能胜任管理员哈。

    如果说目前我对webman的贡献第一,tinywan贡献绝对就是第二(看本页右上角月贡献榜),tinywan提交了大量代码包括大量的插件(昨天还在贡献代码文档),提出建设性意见,给webman补充文档,写分享、在外积极宣传webman,写技术博客、教程等、不定时的捐赠webman/workerman,并且积极回复社区的各种提问。你说他不能胜任,那谁能呢?

    管理员的基本要求:技术好,对社区有一定贡献(只会提问不算),人品好(最起码不背后说别人坏话)。
    如果你想当管理先达到基本要求吧,然后我们再聊。

  • nitron 2022-03-07

    walkor敞亮!
    能接受不同的看法及意见,这就是我一直都比较喜欢workerman/webman的原因
    以前用过一段swoole,还有某前端框架,这里面的人真的是听不得一点不同意见,稍微讲点不足直接一帮人怼你
    跟李某人怼了一场后果断不再接触这个了,我能写go,能写rust,能写elixir/erlang,犯不着一定要用sw
    从旧有PHP项目(基本是laravel系)转webman也简单便捷,

  • li914 2022-03-07

    哈哈哈 感觉不需要群管理员

年代过于久远,无法发表回答
×
🔝