Laravel 5.3 промежуточное ПО SubstituteBindings с проблемой withoutMiddleware
начиная с Laravel 5.3, неявная привязка маршрута работает как промежуточное ПО SubstituteBindings
. Я работал с Laravel 5.2 и 5.3 сейчас.
у меня есть пользовательские middlewares в моем приложении, и в моих тестах мне иногда нужно отключить их. Поэтому до сих пор я использовал $this->withoutMiddleware()
методы испытаний. Но с момента обновления до Laravel 5.3,withoutMiddleware
останавливает неявную привязку маршрута, и все мои тесты терпят неудачу.
Я не знаю, если это считать ошибкой, но это огромная проблема для меня.
Есть ли способ установить SubstituteBindings
middleware как обязательное промежуточное ПО, которое withoutMiddleware
не отключить? Как я могу использовать неявную привязку и тестировать свои тесты без других промежуточных программ?
1 ответов
основываясь на моем комментарии выше, я посмотрел на регистрацию пользовательского маршрутизатора, который всегда добавляет SubstituteBindings
в список промежуточного ПО, если промежуточное ПО было отключено. Вы можете достичь этого, зарегистрировав custom RoutingServiceProvider
и зарегистрировать свой собственный Router
класса. К сожалению, поскольку маршрут создается довольно рано в процессе начальной загрузки приложения, вам также нужно создать пользовательский класс приложения и использовать его в bootstrap/app.php
тоже.
RoutingServiceProvider
<?php namespace App\Extensions\Providers;
use Illuminate\Routing\RoutingServiceProvider as IlluminateRoutingServiceProvider;
use App\Extensions\ExtendedRouter;
class RoutingServiceProvider extends IlluminateRoutingServiceProvider
{
protected function registerRouter()
{
$this->app['router'] = $this->app->share(function ($app) {
return new ExtendedRouter($app['events'], $app);
});
}
}
настраиваемый маршрутизатор
это добавляет промежуточное ПО, оно просто расширяет маршрутизатор по умолчанию, но переопределяет runRouteWithinStack
способ и, вместо того, чтобы возвращать пустой массив, если $this->container->make('middleware.disable')
верно, он возвращает массив, содержащий SubstituteBindings
класса.
<?php namespace App\Extensions;
use Illuminate\Routing\Router;
use Illuminate\Routing\Route;
use Illuminate\Routing\Pipeline;
use Illuminate\Http\Request;
class ExtendedRouter extends Router {
protected function runRouteWithinStack(Route $route, Request $request)
{
$shouldSkipMiddleware = $this->container->bound('middleware.disable') &&
$this->container->make('middleware.disable') === true;
// Make sure SubstituteBindings is always used as middleware
$middleware = $shouldSkipMiddleware ? [
\Illuminate\Routing\Middleware\SubstituteBindings::class
] : $this->gatherRouteMiddleware($route);
return (new Pipeline($this->container))
->send($request)
->through($middleware)
->then(function ($request) use ($route) {
return $this->prepareResponse(
$request, $route->run($request)
);
});
}
}
Пользовательский Класс Приложения
<?php namespace App;
use App\Extensions\Providers\RoutingServiceProvider;
class MyCustomApp extends Application
{
protected function registerBaseServiceProviders()
{
parent::registerBaseServiceProviders();
$this->register(new RoutingServiceProvider($this));
}
С помощью специального приложения класс!--18-->
на bootstrap/app.php
измените строку, в которой экземпляр приложения:
$app = new App\MyCustomApp(
realpath(__DIR__.'/../')
);
--
предупреждение! я не полностью протестировал это, мое приложение загружается и мои тесты проходят, но могут быть проблемы, которые я не обнаружил. Он также довольно хрупкий, так как если база Laravel Router
изменения класса вы можете найти вещи ломаются случайным образом на будущих обновлениях.
--
возможно, вы также хотите, чтобы рефакторинг это так список промежуточного ПО в пользовательском маршрутизаторе всегда содержит SubstituteBindings
класс, поэтому нет большой разницы в поведении, если промежуточное ПО отключено.