好的,我知道这可能是不可能的,但我会试一试。也许我的知识不太好。请不要downvote,这只是为了好奇,这可能是由于糟糕的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
答案 0 :(得分:1)
没有正确的方法来修改/替换/添加类方法。
runkit
扩展程序有runkit_method_redefine()
和runkit_method_add()
,但两者都是实验性的和丑陋的(它们采用代码字符串,而不是像匿名函数一样的Closure对象)。
答案 1 :(得分:0)
我真的不清楚你要做什么,但在PHP中你可以通过编写B类声明来使calss B扩展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
}
希望这有帮助。
答案 2 :(得分:0)
简短的回答是否定的。
你能得到的最接近的是:
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中,继承或组合或依赖注入可能是你正在尝试做什么的正确方法。 (上面的黑客肯定是不你应该做什么。)