Laravel 6-7如何覆盖/更改供应商类别?

t9eec4r0  于 2022-11-26  发布在  其他
关注(0)|答案(6)|浏览(215)

我最近遇到了一个问题,我需要更改Laravel的一个供应商文件来获得所需的结果。该文件是vendor/laravel/framework/Illuminate/Routing/CompileRouteCollection.php
在该文件中,需要更改一个函数。

protected function requestWithoutTrailingSlash(Request $request)
{
    $trimmedRequest = Request::createFromBase($request);

    $parts = explode('?', $request->server->get('REQUEST_URI'), 2);

    $trimmedRequest->server->set(
        'REQUEST_URI', rtrim($parts[0], '/').(isset($parts[1]) ? '?'.$parts[1] : '')
    );

    return $trimmedRequest;
}

更具体地说,本部分:rtrim($parts[0], '/').需要删除结尾处的/,以便我的部分路由工作。
我尝试在内部创建自己的自定义类:App\Helpers\CompiledRouteCollection.php。我在其中复制了上面列出的函数并进行了自己的更改。
App\Helpers\CompiledRouteCollection.php

namespace App\Helpers;

use Illuminate\Http\Request;

class CompiledRouteCollection extends \Illuminate\Routing\CompiledRouteCollection
{
    protected function requestWithoutTrailingSlash(Request $request)
    {
        $trimmedRequest = Request::createFromBase($request);

        $parts = explode('?', $request->server->get('REQUEST_URI'), 2);

        $trimmedRequest->server->set(
            'REQUEST_URI', rtrim($parts[0], '').(isset($parts[1]) ? '?'.$parts[1] : '')
        );

        return $trimmedRequest;
    }
}

然后我进入App\Providers\AppServiceProvider,在register函数中运行该函数。

public function register()
{
    $loader = AliasLoader::getInstance();
    $loader->alias('App\Helpers\CompiledRouteCollection', 'Illuminate\Routing\CompiledRouteCollection');
}

但什么也没发生。

更新1

我把我的别名改成了这个:

$loader = AliasLoader::getInstance();
$loader->alias('Illuminate\Routing\CompiledRouteCollection', 'App\Helpers\CompiledRouteCollection');

但是现在在我的Helper类中,当试图访问任何页面时,它会返回以下错误:Class 'Illuminate\Routing\CompiledRouteCollection' not found
对任何有兴趣帮助我的人,非常感谢。如果你需要更多的信息,请让我知道!
如果你需要更多的上下文,我打开了一个关于laravel/framework的问题,它有完整的背景解释here

twh00eeo

twh00eeo1#

我的结果是使用composer来覆盖文件,因为我以前的方法无论如何都不起作用。下面是我所做的。
首先,在composer.json文件的autoload部分,我添加了以下内容:

"exclude-from-classmap": [
    "vendor\\laravel\\framework\\src\\Illuminate\\Routing\\CompiledRouteCollection.php"
],
"psr-4": {
    "App\\": "app/",
    "Illuminate\\": "app/Overrides/"
},

接下来,我在app文件夹中创建了Ovverides文件夹,然后复制了CompiledRouteCollection.php文件并将其粘贴到Ovverides文件夹中。

b1uwtaje

b1uwtaje2#

编辑app\Providers\AppServiceProvider.phpalias()方法的第一个参数必须是vendor类,后面是覆盖类:

public function register()
{
    $loader = AliasLoader::getInstance();
    $loader->alias(CompileRouteCollection::class, CompiledRouteCollection::class);
}

public function register()
{
    $loader = AliasLoader::getInstance();
    $loader->alias('Illuminate/Routing/CompileRouteCollection', 'App\Helpers\CompiledRouteCollection');
}
jq6vz3qz

jq6vz3qz3#

您可以在composer中覆盖供应商类
您需要编辑composer.json文件并在autoload部分中添加两行额外的代码来替换实现。

"exclude-from-classmap": ["vendor/packagename/diraction/to/File.php"],
"files": ["app/Overrides/File.php"]

第一行将从加载中排除原始类,第二行将指向具有适合您的实现的命名空间的原始类。
那么您需要创建app/Overrides文件夹并将File.php(您要覆盖的文件)复制到其中。
最后一步是运行:

composer dump-autoload

你可以走了!

csga3l58

csga3l584#

尝试在RouteServiceProvider而不是AppServiceProvider中将其交换出来
只是猜测,因为它是路由系统的一部分。它可能在到达AppServiceProvider之前就已经作为原始类被调用了。
我在https://github.com/laravel/framework/issues/32082上看到了你的问题,我很惊讶他们没有建议尝试它。如果我没有记错Laravel的请求生存期,RouteServiceProvider * 可能 * 是你的票。
我很佩服你在寻找变通办法方面的足智多谋。

uklbhaso

uklbhaso5#

根据我的经验,你可以这样做:
1.将以下内容添加到App\Providers\AppServiceProvider中的寄存器函数中。

public function register()
{
    $loader = AliasLoader::getInstance();
    $loader->alias('Illuminate\Routing\CompileRouteCollection', 'App\Helpers\CompiledRouteCollection');
}

1.像这样编辑composer文件。

"psr-4": {
    "App\\": "app/",
    "Illuminate\\Routing\\": "app\\Helpers\\"
},

然后请compose install并运行该项目。

oyt4ldly

oyt4ldly6#

您可能想要使用AppServiceProvider上的$bindings
https://laravel.com/docs/9.x/providers#the-bindings-and-singletons-properties
在本例中,我想覆盖一个包的Login Controller中的$redirectTo变量:
第一个

相关问题