Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call a base class' member function explicitly static

I have a base class with the magic methods __call and _callStatic defined, so that calls to undeclared member functions are handled.

When You have both, the non-static and static ones, it seems to not be possible to call the static one from a derived class, because the static operator :: does not implicitly mean static if used with parent or, as in this case, the name of the base class. This is a special syntax explained here: http://php.net/manual/pl/keyword.parent.php

What I want to do here is the derived class to call __callStatic which fails because the call defaults to being a non-static call and being handled by __call.

How can I make an explicitly static call on a base class' member function?

<?php

class MyBaseClass {

    public static function __callStatic($what, $args)
    {
        return 'static call';
    }
    
    public function __call($what, $args)
    {
        return 'non-static call';
    }

}

class MyDerivedClass extends MyBaseClass {

    function someAction()
    {
        //this seems to be interpreted as parent::Foo()
        //and so does not imply a static call
        return MyBaseClass::Foo(); //
    }

}

$bar = new MyDerivedClass();
echo $bar->someAction(); //outputs 'non-static call'

?>

Note that removing the non-static __call method makes the script output 'static call' because the __callStatic is called, when __call is not declared.

like image 969
Andre Avatar asked Jun 22 '12 11:06

Andre


1 Answers

To avoid such behaviour you may use an empty proxy class, that is not linking parent and MyBaseClass during runtime:

class MyBaseClass {

    public static function __callStatic($what, $args)
    {
        return 'static call ' . PHP_EOL;
    }

    public function __call($what, $args)
    {
        return 'dynamic call ' . PHP_EOL;
    }
}

class ProxyClass extends MyBaseClass {
    //"Empty" class
}

class MyDerivedClass extends MyBaseClass {

    function someAction()
    {
        return ProxyClass::Foo();
    }

}

$bar = new MyDerivedClass();
var_dump($bar->someAction()); //outputs 'static call'

http://pastebin.com/7JMJUmXt

like image 87
Evgeniy Chekan Avatar answered Oct 08 '22 16:10

Evgeniy Chekan