我想将Laravel框架提供的服务替换为我自己的服务,该服务扩展了相同的Laravel服务。在这种特定情况下,我想交换BladeCompiler
服务。
Laravel提供的默认ViewServiceProvider
的作用如下:
use Illuminate'View'Engines'BladeCompiler;
use Illuminate'View'Engines'CompilerEngine;
...
public function registerBladeEngine($resolver)
{
$app = $this->app;
$resolver->register('blade', function() use ($app)
{
$cache = $app['path.storage'].'/views';
$compiler = new BladeCompiler($app['files'], $cache);
return new CompilerEngine($compiler, $app['files']);
});
}
我唯一需要做的就是扩展提供程序,重写方法并替换编译器类。在这种情况下,My'View'Engines'BladeCompiler
。
但要做到这一点,我必须将所有函数复制并粘贴到我的服务提供商,只需替换use
语句。这是一种糟糕的方法,因为对Laravel这一部分的任何修改都会破坏我的应用程序。
我真正想做的是创建另一个扩展默认刀片编译器类的类,为其添加更多功能
有人有更好的主意吗?
编辑:
我打开了一个描述该问题的问题,Taylor将对4.1进行更改,使扩展服务更加容易(至少是刀片编译器)。
我相信你有两个选择:
- 用您自己的覆盖服务提供商
- 利用BladeCompiler的
extend()
方法
选项1:服务提供商副本&粘贴
您要做的关键事情是用扩展版本覆盖Blade编译器。由于整个继承问题,您必须以与默认服务提供商完全相同的方式来定义它;尤其是这段代码:
$resolver->register('blade', function() use ($app)
{
$cache = $app['path.storage'].'/views';
// This is where your extended class would go.
$compiler = new BladeCompiler($app['files'], $cache);
return new CompilerEngine($compiler, $app['files']);
});
您可以通过以下方式访问服务提供商中的View类"EngineResolver":
$this->app['view']->getEngineResolver()
所有这些加在一起,您只剩下以下内容(替换类名并在适当的情况下修改use
):
<?php
use Illuminate'Support'ServiceProvider;
use Illuminate'View'Engines'CompilerEngine;
class ExtendBladeServiceProvider extends ServiceProvider {
public function register()
{
$resolver = $this->app['view']->getEngineResolver();
$resolver->register('blade', function() use ($app)
{
$cache = $app['path.storage'].'/views';
$compiler = new MyBladeCompiler($app['files'], $cache);
return new CompilerEngine($compiler, $app['files']);
});
}
}
因此,是的,您基本上是在复制现有服务提供商的代码。但据我所知,你不得不这么做。我不知道你为什么担心Laravel会改变你的应用程序;你实际上依赖于Laravel组件,所以任何变化都可能破坏一切。使用无法控制的组件会带来风险。
选项2:BladeCompiler的extend()
方法
这几乎可以在应用程序中任何有意义的地方进行。您不会在传统意义上扩展BladeCompiler
类,但您可以实现自己的一组编译函数来运行。
extend()
将提供的闭包添加到在编译期间迭代的数组中。它本质上与扩展类方法相同,不需要重新实例化CompileEngine之类的东西。
注册这些扩展的一种选择是使用服务提供商的boot()
方法(您也可以使用register()
,只需确保按正确的顺序进行):
public function boot()
{
$blade = $this->app['view']->getEngineResolver()->resolve('blade')->getCompiler();
$blade->extend(function($value) use ($blade)
{
$matcher = $blade->createMatcher('myfeature');
return preg_replace($matcher, '<?php echo MyFeature::make$2; ?>', $value);
});
}
您可以查看TwigBridge包的服务提供商。该包所做的是注册另一个视图处理程序(在本例中为.tritch文件)。既然你可能想为你的扩展刀片文件(.bladex?)有一个不同的扩展名,你可以做一些类似的事情
[警告:未经测试的代码]
$app['view']->addExtension('bladex','bladex',function() use($app)
{
$cache = $app['path.storage'].'/views';
$compiler = new BladeXCompiler($app['files'], $cache);
return new CompilerEngine($compiler, $app['files']);
}