【问题标题】:Laravel 5.2 - Updated and Route group Middleware now is no longer calledLaravel 5.2 - 更新和路由组中间件现在不再被调用
【发布时间】:2016-03-30 03:48:33
【问题描述】:

所以我在最新的 Laravel 5.1 上,今天更新到 5.2。在我的路线中,我有这样的事情:

Route::group(['middleware' => ['api']], function() {
    // Members
    Route::get('members', '{api-namespace}\MembersController@index');
    Route::get('member/{id}', '{api-namespace}\MembersController@show');

    // Members Pension
    Route::get('member/{id}/pension/beneficiaries', '{api-namespace}\Inquiry\MembersPensionController@showBeneficiaries');
    Route::get('member/{id}/pension/contributions', '{api-namespace}\Inquiry\MembersPensionController@showContributions');
    Route::get('member/{id}/pension/yearlySummary', '{api-namespace}\Inquiry\MembersPensionController@showYearlySummary');
    Route::get('member/{id}/pension/pensioners', '{api-namespace}\Inquiry\MembersPensionController@showPensioners');

    // Members Summary
    Route::get('member/{id}/beneficiaries/{fund?}', '{api-namespace}\BeneficiariesController@showByMember');
    Route::get('member/{id}/contributions/', '{api-namespace}\ContributionsController@showByMember');

    // Beneficiaries
    Route::get('beneficiaries', '{api-namespace}\BeneficiariesController@index');
    Route::get('beneficiary/{id}', '{api-namespace}\BeneficiariesController@show');

    // Contributions
    Route::get('contributions', '{api-namespace}\ContributionsController@index');

    Route::get('users', '{api-namespace}\UsersController@index');
});

api-version 中间件基本上检查 api-version 的标头,然后在路由操作中适当地填写 {api-namespace}。这在 5.1 中运行良好。但是,自从升级后,我得到了Class App\\Http\\Controllers\\{api-namespace}\\MembersController does not exist,它甚至根本没有影响我的中间件。我有一种感觉,他们可能已经切换了代码的顺序,以便在运行中间件之前验证路由操作,因为如果我将中间件放在全局范围内,它就可以正常工作。但是,我需要这个 api-version 组,所以如果有人知道如何解决这个问题,我会全力以赴。

根据要求:

内核.php

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * @var array
     */
    protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    ];

    /**
     * The application's route middleware.
     *
     * @var array
     */
    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'api-version' => \App\Http\Middleware\ApiVersionMiddleware::class,
    ];

    /**
     * The application's route middleware groups.
     *
     * @var array
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
        ],
        'api' => [
            'throttle:60,1',
            'api-version',
            'cors'
        ],
    ];
}

ApiVersionMiddleware.php

<?php namespace App\Http\Middleware;

use Closure;
use Jbm\Exceptions\ApiVersionException;
use Jbm\Helpers\ApiVersion;

class ApiVersionMiddleware
{

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $route = $request->route();
        $actions = $route->getAction();

        $requestedApiVersion = ApiVersion::get($request);
        if (!ApiVersion::isValid($requestedApiVersion)) {
            throw new ApiVersionException('Invalid API Version');
        }

        $apiNamespace = ApiVersion::getNamespace($requestedApiVersion);

        $actions['uses'] = str_replace(
            '{api-namespace}', $apiNamespace, $actions['uses']
        );

        $route->setAction($actions);

        return $next($request);
    }
}

另请注意,我将中间件移到了中间件组中,但它仍然无法正常工作。仅供参考

更新:

我尝试将中间件移动到全局,但此时它的路由信息​​为 0,这意味着它无法修改路由以替换 {api-namespace}。我认为问题是在中间件运行之前检查了“使用”的路线,这显然失败了。谁能确认这一点和/或告诉我如何在 5.2 中实现类似的东西?

更新 2:

所以我发现了这个问题。在Illuminate/Routing/Router.php:834 中,路由器尝试替换隐式绑定。这发生在中间件之前并检查有效“使用”的路由。我不知道如何解决这个问题,因为它完全颠覆了我目前正在做的事情。有什么建议吗?

【问题讨论】:

  • 这可能与 Laravel 5.2 试图将模型/类自动注入控制器调用有关。请参阅Laravel 5.2 release notes 的“隐式模型绑定”部分
  • 我实际上认为这与此有关:mattstauffer.co/blog/middleware-groups-in-laravel-5-2。他们已经制作了中间件组,调用中间件组的语法与之前将中间件附加到路由组的语法相同......所以它可能会发生冲突。去测试
  • 错误信息暗示它正在尝试根据您的路径绑定到模型,但找不到模型
  • 既然您提到api-version 中间件根本没有收到任何命中,请检查并确保它具有正确的命名空间,确保您已在 $routemiddleware 中的 kernel.php 中注册了中间件,如果可能,请更新您的整个api-version中间件的问题
  • 我已经更新了这个问题.....也许我需要将我的“标签”更改为 api-namespace 不干扰隐式模型绑定的东西?

标签: php laravel laravel-5 laravel-5.1 laravel-5.2


【解决方案1】:

所以这实际上最终成为了一个错误,现在从最新版本的 laravel 5.2 中得到修复:请参阅此处https://github.com/laravel/framework/issues/11261

【讨论】:

    猜你喜欢
    • 2018-04-28
    • 1970-01-01
    • 2016-08-27
    • 2022-01-11
    • 2017-07-03
    • 2017-07-23
    • 2016-05-24
    • 1970-01-01
    • 2017-11-22
    相关资源
    最近更新 更多