好的,我知道这可能是不可能的,但我会尝试一下。也许我的知识不太好。请不要投反对票,这只是出于好奇,可能是因为OO设计不好。
假设A
的类定义为:
class A
{
public function build()
{
$data = $this->fetchData();
...
}
public function fetchData()
{
// Database eavy query
return $this->repository->fetchDataForCharting();
}
}
然后,在不使用良好和体面的OO设计的情况下,创建类B
,该类将使用存储库中的fetchDataForCharting
来进行其他一些不同的计算:
class B
{
public $data;
public function getMonthlyLimit()
{
// Database eavy query
$data = $this->getData();
}
public function getData()
{
return isset($this->data) ? $this->data :
$this->repository->fetchDataForCharting();
}
}
有时你只需要A
,有时你只需B
,有时两者兼而有之。有什么方法可以在运行时覆盖fetchData
吗?我的意思是像jQuery中的$.extend()
:
$b = new B();
$b->getMonthlyLimit(); // $b->data filled
$a = new A();
// Override fetchData
$a = extend($a, 'fetchData', function() use($b) { return $b->data; });
$a->build(); // Just 1 query
没有正确的方法来修改/替换/添加类方法。
runkit
扩展有runkit_method_redefine()
和runkit_method_add()
,但它们都是实验性的,而且很难看(它们采用的是代码字符串,而不是像匿名函数那样的闭包对象)。
我并不清楚你想做什么,但在PHP中,你可以让calss B通过如下方式编写class B声明来扩展class A:
Class B extends Class A {
...
}
您可以覆盖类B中的fetchData函数,如
public function fetchData {
// do something different than in class A
}
或
public function fetchData {
// execute the Class A functionality first
parent::fetchData();
// now do something in addition to what is in Class A functionality
}
希望这能有所帮助。
简短的回答是否定的。
你能最接近你所要求的是:
class A
{
public function __construct()
{
$this->bar = function()
{
};
}
public function foo()
{
$bar = $this->bar;
$bar();
}
}
$a = new A();
$a->bar = function()
{
// override
};
$a->foo();
需要PHP 5.4才能支持$this
。但请记住,人们在JavaScript中做这种事情是因为它没有"真正的"面向对象编程。你不应该仅仅为了模仿JavaScript、Ruby、Python等
需要明确的是:在PHP中,继承、组合或依赖项注入可能是实现您想要做的事情的正确方法