Reputation: 1847
I'm writing a plugin for WooCommerce, Today something came across my mind suddenly, I was thinking if there is a way to expend PHP Classes like the way we do that in JavaScript without touching anything in the PHP class( Since WooCommerce will get updated and our changed will be gone ).
I found solutions like using __call
method but like i said, the class shouldn't be edited. I want to be able to use something like this WC()->My_custom_method()
without touching Woocommerce class.Is it even possible?
For example in JavaScript all we need to do is :
Foo.prototype.bar = function (){
// ...
}
Foo.bar();
Upvotes: 2
Views: 178
Reputation: 317119
PHP does not have prototypical inheritance and classes have no prototype like in JavaScript. You can simulate what you are asking with some hackery, but that will ultimately result in hard to maintain code. So don't go there.
There is a GitHub project at https://github.com/bdelespierre/prototype.php with a Proof of Concept implementation. You might find it interesting to study.
Needless to say, if your aim is just to add some functionality to a class, you can still use PHP's inheritance, e.g. extend the WooCommerce class and add your modifications in the subclass. Then use an instance of that new class instead, e.g.
class MyClass extends SomeWooCommerceClass {
public function bar() {
// your own implementation of bar
}
}
$myObj = new MyClass();
$myObj->bar();
If your aim is to change the behavior of an existing object instance, consider wrapping the instance into a Decorator, e.g.
class WooCommerceDecorator {
private $instance;
public function __construct(SomeWooCommerceClass $instance) {
$this->instance = $instance;
}
public function foo() {
$original = $this->instance->foo();
$original+= 42;
return $original;
}
// … more methods
Then use it by passing the object to the decorator:
$woo = new SomeWooCommerceClass();
$decoratedWoo = new WooCommerceDecorator($woo);
echo $decoratedWoo->foo();
Also see the PHP manual on Inheritance
Upvotes: 3
Reputation: 3018
I don't recommend this but you could do something like
class Test {
private $myMethods = array();
public addMethod($name, $func) {
$myMethods[$name] = $func;
}
public callMethod() {
$myMethods[$name]();
}
}
....
$test->addMethod("doSomething", function(){ echo 123;});
$test->callMethod("doSomething");
I didn't test the code it's just an idea
Upvotes: 1
Reputation: 43507
Your best call would be to use extended class.
class MyClass extends Foo {
public function methodInFoo() {
echo "I Am extended";
parent::methodInFoo();
}
public function additionalFunction() {
echo "I am new method that is not presented in Foo";
}
}
That way you even can have Composer to auto-update core classes and while you are using this extended class, you will have your own functions along with all functionality in core class.
Upvotes: 1