我正在尝试延长Kryptonit3/Counter。特别是,我需要覆盖Counter.php类中的一个私有函数来检索过去24小时内的命中。
Counter.php私人功能:
private static function countHits($page)
{
$page_record = self::createPageIfNotPresent($page);
return number_format($page_record->visitors->count());
}
我需要的功能:
private static function countHits($page)
{
$page_record = self::createPageIfNotPresent($page);
return number_format($page_record->visitors()->where('created_at', '>=', Carbon::now()->subDay())->count());
}
因此,我正在寻找覆盖此软件包的正确方法。
方法1 :我应该创建自己的类来扩展Counter.php并在此类中包含我的自定义函数吗?如果是这样,原始类中包含的私有类会发生什么?我应该创建服务提供商吗?这个服务提供商的样子如何?
方法2 :我应该分叉供应商包并根据自己的需要更新此包吗?
我已经查看了与此主题相关的所有stackoverflow问题,但它们不够清晰。
更新 这就是我到目前为止所做的:
创建MyCounter类:
<?php
namespace App\Helpers\Counter;
use Kryptonit3\Counter\Counter;
class MyCounter extends Counter
{
}
创建MyCounterServiceProvider:
<?php
namespace App\Providers;
use App\Helpers\MyCounter;
use Illuminate\Support\ServiceProvider;
class MyCounterServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
$this->app['counter'] = $this->app->share(function($app)
{
$visitor = $app['visitor'];
return new MyCounter($visitor);
});
}
}
创建MyCounterFacade:
<?php
namespace App\Helpers\Counter;
use Illuminate\Support\Facades\Facade;
class MyCounterFacade extends Facade
{
protected static function getFacadeAccessor() { return 'mycounter'; }
}
在config / app.php中包含提供程序和别名:
App\Providers\MyCounterServiceProvider::class,
和
'MyCounter' => App\Helpers\Counter\MyCounterFacade::class,
答案 0 :(得分:0)
静态方法不能静态覆盖,但您可以使用__callstatic以动态覆盖它们:
Route::get('/override', function() {
$b = new ClassB();
dd($b::originalMethod());
});
class ClassA {
private static function originalMethod() {
return 'Original value from ClassA';
}
public function callingOriginalMethodMethod()
{
return static::originalMethod();
}
}
class ClassB {
public static function __callStatic($name, $arguments) {
if ($name == 'originalMethod') {
return static::overloadedMethod();
}
return forward_static_call_array(array(ClassA::class, $name), $arguments);
}
protected static function overloadedMethod() {
return 'Overloaded value from ClassB';
}
}
点击/覆盖,你应该看到
Overloaded value from ClassB
话虽如此,你能做什么:
为该类创建覆盖:
<?php
namespace App\Helpers;
use Kryptonit3\Counter\Counter;
class MyCounter extends Counter
{
public static function __callStatic($name, $arguments) {
if ($name == 'countHits') {
return static::myCountHits($page);
}
return forward_static_call_array(array(Counter::class, $name), $arguments);
}
protected static function myCountHits($page) {
return 'whatever';
}
}
然后您只需覆盖counter
的原始实例。
app()->singleton('counter', function() {
return app()->make(MyCounter::class);
});
答案 1 :(得分:0)
问题与MyCounterServiceProvider有关。下一段代码解决了这个问题。
public function register()
{
$this->app->singleton('mycounter', function() {
return $this->app->make('App\Helpers\Counter\MyCounter');
});
}