拦截 Laravel 路由

Posted

技术标签:

【中文标题】拦截 Laravel 路由【英文标题】:Intercept Laravel Routing 【发布时间】:2015-10-11 03:47:23 【问题描述】:

我正忙于在 Laravel 5.1 中构建一个 Restful API,其中 API 版本通过标头传递。这样我可以对功能进行版本控制,而不是复制和粘贴整个路由组并增加版本号。

我遇到的问题是我想要版本化的方法,IE:

public function store_v1 ()  

我在路由上添加了一个中间件,我从标头中捕获版本,但现在需要修改请求以从控制器中选择正确的方法。

app/Http/routes.php

Route::group(['middleware' => ['apiversion']], function()

    Route::post('demo', 'DemoController@store');

app/Http/Middleware/ApiVersionMiddleware.php

public function handle($request, Closure $next)

    $action = app()->router->getCurrentRoute()->getActionName();

    //  dd($action)
    //  returns "App\Http\Controllers\DemoController@store"

从这里开始,我会将标头版本附加到 $action,然后通过 $request 传递它,以便它到达正确的方法。

嗯,这就是理论。

关于如何将动作注入路线的任何想法?

【问题讨论】:

【参考方案1】:

我认为中间件可能不是这样做的最佳场所。您可以访问该路由,但它不提供修改将被调用的控制器方法的方法。

更简单的选择是注册一个自定义路由调度程序,该调度程序根据请求和路由处理调用控制器方法的逻辑。它可能看起来像这样:

<?php

class VersionedRouteDispatcher extends Illuminate\Routing\ControllerDispatcher 
  public function dispatch(Route $route, Request $request, $controller, $method)
  
    $version = $request->headers->get('version', 'v1'); // take version from the header
    $method = sprintf('%s_%s', $method, $version); // create target method name
    return parent::dispatch($route, $request, $controller, $method); // run parent logic with altered method name
  

一旦你有了这个自定义调度器,在你的 AppServiceProvider 中注册它:

public function register() 
  $this->app->singleton('illuminate.route.dispatcher', VersionedRouteDispatcher::class);

这样,您将使用自己的路由调度程序覆盖默认路由调度程序,该调度程序将使用从请求标头中获取的版本作为控制器方法名称的后缀。

【讨论】:

这个方法很遗憾在 5.2 中被移除了。请参阅***.com/a/36779587/926953 了解替代(但功能较弱)选项。【参考方案2】:

一种粗略的替代方法是在您的公用文件夹中创建指向公用文件夹的符号链接。使用中间件读取 url 并设置可在控制器中使用的全局配置以确定要显示的内容。不理想,但有效。

【讨论】:

以上是关于拦截 Laravel 路由的主要内容,如果未能解决你的问题,请参考以下文章

laravel 路由参数的默认值怎么设置

【PHP】laravel中获取当前路由名称

laravel5.4学习--laravel基本路由

Laravel反向路由的好处

Laravel 路由

Laravel 路由