I have a PHP library which I don't want to edit, and implement to my code by extending/overriding some methods. But I'm stuck with chainability. For example:
class MomentPHP extends Moment {
public $uniqueSettings;
public function formatJS(){
return parent::format($this->uniqueSettings);
}
}
class Moment {
public function startOf(){
//some code
return $this;
}
}
I want to do this:
$momentphp = new MomentPHP();
$dateStart = $momentphp->startof('month')->formatJs();
And the way to do this is overriding all the methods in the child class inside MomentPHP to return itself.
Is there any other simple way to do this? like using _call
or something?
Edit: Found one way to do this:
__call
method to switch between classes.Like this:
class MomentPHP {
private $instance = null;
public $uniqueSettings;
public function __construct(){
$this->instance = new Moment();
}
public function __call($method,$args){
if(in_array($method, get_class_methods($this))){
call_user_func(array($this,$method),$args);
else
call_user_func(array($this->instance,$method),$args);
return $this;
}
public function formatJS(){
return $this->instance->format($this->uniqueSettings);
}
}
class Moment {
public function startOf(){
//some code
return $this;
}
}
Is there any better way?
One proper way to do this is:
class MomentPHP {
private $instance = null;
public $uniqueSettings;
public function __construct(){
$this->instance = new Moment();
// settings etc.
}
public function __call($method,$args){
$result = NULL;
if(in_array($method, get_class_methods($this))){
$result = call_user_func(array($this,$method),$args);
else
$result = call_user_func(array($this->instance,$method),$args);
if($result instanceof Moment)
$this->instance = $result;
return $this;
}
public function format(){
return $this->instance->format($this->uniqueSettings);
}
}
Updating the instance from the method result is the key operation, and using $this
instead of $this->instance
allows you to use the extender class in every call. So you can override the function while using other methods in the parent class with chaining ability.