Amin Abdolrezapoor
Amin Abdolrezapoor

Reputation: 1847

Is there any way to add methods to php classes like in javascript?

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

Answers (3)

Gordon
Gordon

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

ave4496
ave4496

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

Justinas
Justinas

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

Related Questions