gremo gremo - 3 months ago 8
PHP Question

Overriding an instance method without inheritance in PHP?

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

Answer

There is no proper way to modify/replace/add a class method.

The runkit extension has runkit_method_redefine() and runkit_method_add() but both are experimental and ugly (they take a code string, not a Closure object like your anonymous function is).