Ok, i know that probably this is not possible, but i’ll give it a try. Maybe my knowledge is not so good. Please don’t downvote, this is just for curiosity and this maybe due to a poor OO design.
Assume that class definition for A is:
class A
{
public function build()
{
$data = $this->fetchData();
...
}
public function fetchData()
{
// Database eavy query
return $this->repository->fetchDataForCharting();
}
}
And then, without using a good and decent OO design, you create class B which is going to use fetchDataForCharting from the repository, for doing some other different calculations:
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();
}
}
Sometimes you need only A, sometimes you need only B, sometimes both. Is there any way of overriding fetchData at runtime? I mean someting like $.extend() in jQuery:
$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
There is no proper way to modify/replace/add a class method.
The
runkitextension hasrunkit_method_redefine()andrunkit_method_add()but both are experimental and ugly (they take a code string, not a Closure object like your anonymous function is).