Расширить класс 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 и т. Д.

Другие вопросы по тегам