应用是从控制器判断,有些反直觉

ichynul

问题描述

App::getAppByController 中判断所属应用,有些问题

Route::any('/api/areacity/province', [\xxx\yyy\api\controller\Areacity::class, 'province']);

像这种路由绑定的,直觉上应该属于api应用,但实际上是yyy,导致整跨域老是不行。

优化建议

改为通过请求路径判断,分割路径,app预留给插件,其他的取第一个。

或者在现有基础上优化,路径分割后取controller前面的一个。

221 2 0
2个回答

Tinywan

你应该使用路由分组

  • ichynul 2天前

    跟那个没关系,理论上可以直接在路由定义的时候就绑定中间件。
    但实际情况是,下面的路由是由composer包提供,他定义了一个/api/前缀的路由。
    现在只需要把/api/前缀支持跨域就行。

主流框架对应用的定义基本都是app下的目录,和url没有直接关系。

url语义太灵活了,很多时候无法通过url判定哪个是应用,哪个是控制器。

例如 /user/100 user是应用?实际它可能是控制器
例如 /user/get/100 user是应用?实际它可能是控制器
例如 /admin/user/get/100 admin是应用?实际可能是 /app/controller/admin/ 目录,没有多应用的意思。
例如 /en/user/get/100 en是应用?实际它只代表一个语言
例如 /v1/user/get/100 v1是应用?实际是接口版本

url有丰富的语义,你不能规定死那部分是应用,哪部分是控制器
所以具体哪个应用就看实际调用的控制器属于哪个应用,不看url路径。

  • pengzhen 1天前

    大佬,看下gateway worker 的 pr请求

  • ichynul 1天前

    现有的只考虑插件和app目录下的情况,其余情况(比如基础插件里面路由绑定的)取controller前一位应该比较科学

            $controllerClass = trim($controllerClass, '\\');
            $tmp = explode('\\', $controllerClass, 5);
            if (in_array($tmp[0], ['app', 'plugin'])) {
                $pos = $tmp[0] === 'plugin' ? 3 : 1;
                if (!isset($tmp[$pos])) {
                    return '';
                }
                return strtolower($tmp[$pos]) === 'controller' ? '' : $tmp[$pos];
            }
            foreach ($tmp as $pos => $name) {
                if (strtolower($name) === 'controller') {
                    return $tmp[$pos - 1];
                }
            }
            return '';
  • walkor 1天前

    要么以目录为准,要么以url为准,两个都参考就更乱了。
    框架不能规定死url哪里是应用,哪里是控制器。

    例如 /en/user/get/100 en是应用?
    例如 /v1/user/get/100 v1是应用?
    还有更多千奇百怪的url,你怎么强制规定?

🔝