2

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();
7
  • Why don't you inherit the class into some other custom class of yours using extends ? Commented Dec 15, 2016 at 14:48
  • @AbhayMaurya It's not an issue , i was just thinking if such thing is possible in PHP? Commented Dec 15, 2016 at 14:50
  • Yes it does work in OOP PHP. Its same like java if you are familiar with class inheritance. You can leave the class you dont want to disturb as it is and create your own class inheriting the main one to get access to its property and then you can manage everything in your own custom class. For more reference see this: php.net/manual/ro/language.oop5.inheritance.php Commented Dec 15, 2016 at 14:52
  • @AbhayMaurya No I'm not talking about class inheritance , i already know about that , i was wondering if there is a way to add a method directly to a class from outside of that class without touching the class itself !? Commented Dec 15, 2016 at 14:55
  • You should use composition or inheritance to extend a classes functionality. Commented Dec 15, 2016 at 15:56

3 Answers 3

3

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

Sign up to request clarification or add additional context in comments.

1 Comment

that will ultimately result in hard to maintain code
1

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.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.