Laravel 6-7 我怎样才能 Override/Change 成为供应商 Class?
Laravel 6-7 How Can I Override/Change a Vendor Class?
我最近 运行 遇到一个问题,我需要更改 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], '/')
。最后的那个 / 需要被删除,以便我的部分路线能够正常工作。
我尝试在里面创建自己的自定义 class: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 并且我 运行 在寄存器函数里面。
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');
但现在在我的助手 class 它 returns 尝试访问任何页面时出现此错误:
Class 'Illuminate\Routing\CompiledRouteCollection' not found
非常感谢任何有兴趣帮助我的人。如果您需要更多信息,请告诉我!
如果您需要更多上下文,我在 laravel/framework 上提出了一个问题,其中包含完整的背景解释 here
在别名中,第一个参数必须是供应商 class,之后被覆盖 class
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');
}
如你所愿))
我改用 composer 来 ovveride 文件,因为我以前的方法不管用。这是我所做的。
首先,我在 composer.json
文件的自动加载部分添加了以下内容:
"exclude-from-classmap": [
"vendor\laravel\framework\src\Illuminate\Routing\CompiledRouteCollection.php"
],
"psr-4": {
"App\": "app/",
"Illuminate\": "app/Overrides/"
},
接下来,我在应用程序文件夹中创建了 Ovverides 文件夹,然后我复制了 CompiledRouteCollection.php
文件并将其粘贴到 Ovverides 文件夹中。
尝试在 RouteServiceProvider
而不是 AppServiceProvider
中换掉它
只是猜测,因为它是路由系统的一部分。在到达 AppServiceProvider
之前,它可能已经作为原始 class 被调用。
我在 https://github.com/laravel/framework/issues/32082 上查看了您的问题,令我惊讶的是他们没有建议尝试。如果我没记错 Laravel 的请求生命周期,RouteServiceProvider
可能 是你的票。
我很钦佩你在寻找解决方法方面的足智多谋。
根据我的经验,你可以这样做:
- 在
App\Providers\AppServiceProvider
. 的register函数中添加以下内容
public function register()
{
$loader = AliasLoader::getInstance();
$loader->alias('Illuminate\Routing\CompileRouteCollection', 'App\Helpers\CompiledRouteCollection');
}
- 像这样编辑作曲家文件。
"psr-4": {
"App\": "app/",
"Illuminate\Routing\": "app\Helpers\"
},
然后请compose install
和运行项目。
您可以在 composer
中覆盖供应商 classes
您需要编辑您的 composer.json
文件并在自动加载部分添加两行额外的行以替换实现。
"exclude-from-classmap": ["vendor/packagename/diraction/to/File.php"],
"files": ["app/Overrides/File.php"]
第一行将不加载原始 class,第二行 class 将指向原始 class,并为您的实现提供适当的命名空间。
然后您需要创建 app/Overrides
文件夹并将 File.php(您要覆盖的文件)复制到其中。
最后一步是 运行:
composer dump-autoload
一切顺利!
我最近 运行 遇到一个问题,我需要更改 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], '/')
。最后的那个 / 需要被删除,以便我的部分路线能够正常工作。
我尝试在里面创建自己的自定义 class: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 并且我 运行 在寄存器函数里面。
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');
但现在在我的助手 class 它 returns 尝试访问任何页面时出现此错误:
Class 'Illuminate\Routing\CompiledRouteCollection' not found
非常感谢任何有兴趣帮助我的人。如果您需要更多信息,请告诉我!
如果您需要更多上下文,我在 laravel/framework 上提出了一个问题,其中包含完整的背景解释 here
在别名中,第一个参数必须是供应商 class,之后被覆盖 class
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');
}
如你所愿))
我改用 composer 来 ovveride 文件,因为我以前的方法不管用。这是我所做的。
首先,我在 composer.json
文件的自动加载部分添加了以下内容:
"exclude-from-classmap": [
"vendor\laravel\framework\src\Illuminate\Routing\CompiledRouteCollection.php"
],
"psr-4": {
"App\": "app/",
"Illuminate\": "app/Overrides/"
},
接下来,我在应用程序文件夹中创建了 Ovverides 文件夹,然后我复制了 CompiledRouteCollection.php
文件并将其粘贴到 Ovverides 文件夹中。
尝试在 RouteServiceProvider
而不是 AppServiceProvider
只是猜测,因为它是路由系统的一部分。在到达 AppServiceProvider
之前,它可能已经作为原始 class 被调用。
我在 https://github.com/laravel/framework/issues/32082 上查看了您的问题,令我惊讶的是他们没有建议尝试。如果我没记错 Laravel 的请求生命周期,RouteServiceProvider
可能 是你的票。
我很钦佩你在寻找解决方法方面的足智多谋。
根据我的经验,你可以这样做:
- 在
App\Providers\AppServiceProvider
. 的register函数中添加以下内容
public function register()
{
$loader = AliasLoader::getInstance();
$loader->alias('Illuminate\Routing\CompileRouteCollection', 'App\Helpers\CompiledRouteCollection');
}
- 像这样编辑作曲家文件。
"psr-4": {
"App\": "app/",
"Illuminate\Routing\": "app\Helpers\"
},
然后请compose install
和运行项目。
您可以在 composer
中覆盖供应商 classes您需要编辑您的 composer.json
文件并在自动加载部分添加两行额外的行以替换实现。
"exclude-from-classmap": ["vendor/packagename/diraction/to/File.php"],
"files": ["app/Overrides/File.php"]
第一行将不加载原始 class,第二行 class 将指向原始 class,并为您的实现提供适当的命名空间。
然后您需要创建 app/Overrides
文件夹并将 File.php(您要覆盖的文件)复制到其中。
最后一步是 运行:
composer dump-autoload
一切顺利!