Laravel 5.4 - 如何覆盖包中定义的路由?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44723747/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 16:11:55  来源:igfitidea点击:

Laravel 5.4 - How to override route defined in a package?

phplaravellaravel-5.4laravel-routing

提问by António Quadrado

I have created a package in Laravel 5.4 that sets up a basic backoffice. This package contains several routes that are using controllers from within the package. What I want to be able to do is to override the package defined routes in my application in order to plug custom controllers. For example, if I have a route

我在 Laravel 5.4 中创建了一个包,它设置了一个基本的后台。这个包包含几个使用包内控制器的路由。我想要做的是在我的应用程序中覆盖包定义的路由以插入自定义控制器。例如,如果我有一条路线

        Route::get('login', [
            'as' => 'admin.login',
            'uses' => 'Auth\LoginController@showLoginForm'
        ]);

defined in my package that will use the Vendor\Package\Controllers\Auth\LoginControllerI want to defined a route for my application that will override that one and use the App\Controllers\Auth\LoginController.

在我的包中定义,它将使用Vendor\Package\Controllers\Auth\LoginController我想为我的应用程序定义一个路由,该路由将覆盖该路由并使用App\Controllers\Auth\LoginController.

Doing the obvious approach of defining the route in app routes files fails for the app routes files are run before the package routes file, so the package definition will prevail.

在应用路由文件中定义路由的明显方法失败,因为应用路由文件在包路由文件之前运行,因此包定义将优先。

Is there any way to accomplish something of this kind?

有没有办法完成这种事情?

I also tried to get the particular route in the RouteServiceProviderand use the method usesto set the controller that should be used to resolve it, like this

我还尝试获取中的特定路由RouteServiceProvider并使用该方法uses设置应该用于解决它的控制器,如下所示

public function boot()
    {
        parent::boot();
        Route::get('admin.login')->uses('App\Http\Controllers\Admin\Auth\LoginController@showLoginForm');
    }

but this also fails to accomplish what is pretended.

但这也未能实现所假装的。

Any clues on what I am doing wrong?

关于我做错了什么的任何线索?

回答by thefallen

In config/app.phpin the providersarray put the service provider of the package before App\Providers\RouteServiceProvider::class,and then in your web.phproutes you'll be able to override it with your custom route.

config/app.php中的providers数组中,先将包的服务提供者App\Providers\RouteServiceProvider::class,放在你的web.php路由中,然后你就可以用你的自定义路由覆盖它。

EDITFor Laravel package auto discovery you can disable the package being auto discovered in your composer.jsonlike this:

编辑对于 Laravel 包自动发现,您可以composer.json像这样禁用自动发现的包:

"extra": {
    "laravel": {
        "dont-discover": [
            "barryvdh/laravel-debugbar"
        ]
    }
},

In this example the barryvdh/laravel-debugbarpackage won't be autodiscovered, which means you would have to manually include its service provider in the config array and then you'll be able to rearrange your custom provider in the desired order.

在此示例中,barryvdh/laravel-debugbar不会自动发现包,这意味着您必须手动将其服务提供程序包含在 config 数组中,然后您才能按所需顺序重新排列自定义提供程序。

回答by Chris Tyler

Another option -- which doesn't have to muck with the order of service providers -- is to add a binding for the controller. So e.g. in AppServiceProvider,

另一种选择——不必与服务提供者的顺序混淆——是为控制器添加一个绑定。例如在 AppServiceProvider 中,

$this->app->bind(
    \Vendor\Package\Controllers\Auth\LoginController::class,
    App\Controllers\Auth\LoginController::class
);

You'll have to match controller method names, but you're doing that already in your example.

您必须匹配控制器方法名称,但您已经在示例中这样做了。

(Caveat on this answer: I haven't tested it in Laravel 5.4, but I just did this in Laravel 6.0 using the $bindings property which was added in Laravel 5.6. That said, this should be correct 5.4 syntax for doing the same thing).

(这个答案的警告:我没有在 Laravel 5.4 中测试过它,但我只是在 Laravel 6.0 中使用 Laravel 5.6 中添加的 $bindings 属性做了这个。也就是说,这应该是正确的 5.4 语法,用于做同样的事情)。