Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling static function from instance

I'm trying to call a static magic function (__callStatic) from a member of its child class. Problem being, it goes to the non-static __call instead.

<?php

ini_set("display_errors", true);

class a
{
    function __call($method, $params)
    {
        echo "instance";
    }

    static function __callStatic($method, $params)
    {
        echo "static";
    }
}

class b extends a
{
    function foo()
    {
        echo static::bar();
        // === echo self::bar();
        // === echo a::bar();
        // === echo b::bar();
    }
}

$b = new b();
echo phpversion()."<br />";
$b->foo();

?>

Output:

5.3.6
instance

How can I make it display "static"?

like image 918
Lazlo Avatar asked Jul 19 '11 15:07

Lazlo


2 Answers

If you remove the magic method '__call', your code will return 'static'.

According to http://php.net/manual/en/language.oop5.overloading.php "__callStatic() is triggered when invoking inaccessible methods in a static context".

What I think is happening in your code is that,

  1. You are calling static method from a non-static context.
  2. The method call is in non-static context, so PHP searches for the magic method '__call'.
  3. PHP triggers the magic method '_call' if it's exists. Or, if it's not exists it will call '_callStatic'.

Here is a possible solution:

class a
{
    static function __callStatic($method, $params)
    {
        $methodList =  array('staticMethod1', 'staticMethod2');

        // check if the method name should be called statically
        if (!in_array($method, $methodList)) {
            return false;
        }

        echo "static";

        return true;
    }

    function __call($method, $params)
    {
         $status = self::__callStatic($method, $params);
         if ($status) {
             return;
         }
         echo "instance";
    }

}

class b extends a
{
    function foo()
    {
        echo static::staticMethod1();
    }

    function foo2()
    {
        echo static::bar();
    }
}

$b = new b();
echo phpversion()."<br />";
$b->foo();
$b->foo2();
like image 152
satrun77 Avatar answered Oct 24 '22 08:10

satrun77


In PHP there are the reserved words self and parent for accessing static methods from within a class and/or instantiated object. parent refers to inherited methods from the parent class.

class b extends a
{
    function foo()
    {
        echo parent::bar();
    }
}

EDIT: Uhm, that doesn't do the trick… (using PHP 5.3.5)

$b = new b();
$b->foo();  // displays: instance
a::bar();   // displays: static

2nd EDIT: Ha, it works only, if you omit the __call()-method in class a.

class a
{
    static function __callStatic($method, $params)
    {
        echo "static";
    }

//  function __call($method, $params)
//    {
//        echo "instance";
//    }
}

class b extends a
{
    function foo()
    {
        echo parent::bar();
    }
}

$b = new b();
$b->foo();  // displays: static
a::bar();   // displays: static
like image 29
feeela Avatar answered Oct 24 '22 08:10

feeela