Расширить класс Laravels Router (4.1)
Я хотел бы расширить класс Laravels Router (Illuminate\Routing\Router), чтобы добавить метод, который мне очень нужен в моем приложении.
Но, к сожалению, я не могу заставить это работать. Я уже успешно продлил другие классы, поэтому я действительно не знаю, откуда взялось мое неправильное мышление.
Во всяком случае, прямо в код:
<?php
namespace MyApp\Extensions;
use Illuminate\Routing\Router as IlluminateRouter;
class Router extends IlluminateRouter
{
public function test()
{
$route = $this->getCurrentRoute();
return $route->getParameter('test');
}
}
Итак, как вы видите, я хочу получить параметр, заданный {test} в rout.php, с помощью простого вызова, например:
Router:: тест ();
Не уверен, как идти дальше. Пытался привязать его к IOC-контейнеру внутри моего ServiceProvider в register() и boot(), но мне не повезло.
Что бы я ни пытался, я получаю либо ошибку конструктора, либо что-то еще.
Все решения, которые я нашел, устарели, и API изменился с тех пор.
Пожалуйста, помогите мне!
редактировать: я уже пытался связать свой собственный маршрутизатор внутри register() и boot() (как сказано выше), но это не работает.
Вот мой код:
<?php
namespace MyApp;
use Illuminate\Support\ServiceProvider;
use MyApp\Extensions\Router;
class MyAppServiceProvider extends ServiceProvider {
public function register()
{
$this->app['router'] = $this->app->share(function($app)
{
return new Router(new Illuminate\Events\Dispatcher);
}
// Other bindings ...
}
}
Когда я пытаюсь использовать мой маршрутизатор сейчас, у меня возникает проблема, что ему нужен диспетчер.
Так что я должен сделать:
$router = new Router(new Illuminate\Events\Dispatcher); // Else I get an exception :(
Кроме того, он просто ничего не делает, если я позвоню:
$router->test();
:(
И если я позвоню dd($router->test());
Я получаю NULL
3 ответа
Смотреть на: app/config/app.php
и в массиве псевдонимов. Ты увидишь Route
псевдоним маршрутизатора подсветки через класс фасадов.
Если вы посмотрите на класс фасада в Support/Facades/Route.php
источника света, вы увидите, что он использует $app['router']
,
В отличие от многих поставщиков услуг в laravel, маршрутизатор жестко запрограммирован и не может быть заменен без большой работы, переписывающей laravel или редактирующей источник поставщика (оба не являются хорошей идеей). Вы можете увидеть его жестко, перейдя в Illuminate / Foundation / Application.php
и в поисках RoutingServiceProvider
,
Тем не менее, я не могу думать о том, что это помешало бы вам переопределить класс маршрутизатора в сервис-провайдере. Так что, если вы создаете поставщика услуг для своего пользовательского маршрутизатора, который привязывается к $app['router']
, это должно заменить маршрутизатор по умолчанию вашим собственным маршрутизатором.
Я не ожидал, что у этого метода возникнут какие-либо проблемы, так как провайдеры должны быть загружены до того, как будет выполнена какая-либо маршрутизация. Поэтому переопределение маршрутизатора должно произойти до того, как laravel начнет использовать класс маршрутизатора, но я этого не делал раньше, поэтому будьте готовы к небольшой отладке, если она не сработает сразу.
Итак, я спрашивал в официальном IRC Laravel, и кажется, что вы просто не можете больше расширять Router до 4.1. По крайней мере, это все, что я получил в ответ в довольно долгом диалоге.
Это работало в Laravel 4.0, но теперь это не так. Ну что ж, может быть, это снова будет работать в 4.2. Другие пакеты также страдают от этого: https://github.com/jasonlewis/enhanced-router/issues/16
В любом случае, лично я буду придерживаться моего расширенного запроса. Разница не такая большая, просто маршрутизатор был бы более динамичным и лучше подходящим.
Я использую Laravel 4.2, и маршрутизатор действительно жестко запрограммирован в приложении, но я расширил его следующим образом:
Отредактируйте bootstrap/start.php, измените Illuminate\Foundation\Application for YourNamespace\Application.
Создайте класс с именем YourNamespace \ Application и расширьте \Illuminate\Foundation\Application.
class Application extends \Illuminate\Foundation\Application {
/**
* Register the routing service provider.
*
* @return void
*/
protected function registerRoutingProvider()
{
$this->register(new RoutingServiceProvider($this));
}
}
Создайте класс с именем YourNamespace\RoutingServiceProvider и расширьте \Illuminate\Routing\RoutingServiceProvider.
class RoutingServiceProvider extends \Illuminate\Routing\RoutingServiceProvider {
protected function registerRouter()
{
$this->app['router'] = $this->app->share(function($app)
{
$router = new Router($app['events'], $app);
// If the current application environment is "testing", we will disable the
// routing filters, since they can be tested independently of the routes
// and just get in the way of our typical controller testing concerns.
if ($app['env'] == 'testing')
{
$router->disableFilters();
}
return $router;
});
}
}
Наконец, создайте YourNamespace\Router, расширяющий \ Illuminate \ Routing \ Router, и все готово.
ПРИМЕЧАНИЕ. Несмотря на то, что вы не изменяете имя класса, например Router и RoutingServiceProvider, он будет работать из-за разрешения пространства имен, которое будет указывать на YourNamespace\Router и т. Д.