从实例调用静态函数

时间:2011-07-19 15:44:57

标签: php methods static instance

我正在尝试从其子类的成员中调用静态魔术函数(__callStatic)。问题是,它转向非静态__call

<?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();

?>

输出:

5.3.6
instance

如何让它显示“静态”?

2 个答案:

答案 0 :(得分:6)

如果删除魔术方法'__call',您的代码将返回'static'。

根据http://php.net/manual/en/language.oop5.overloading.php“在静态上下文中调用不可访问的方法时会触发__callStatic()”。

我认为您的代码中发生的是

  1. 您正在从非静态上下文中调用静态方法。
  2. 方法调用是在非静态上下文中,因此PHP搜索魔术方法'__call'。
  3. PHP会触发魔术方法'_ 调用'(如果它存在)。或者,如果它不存在,它将调用' _callStatic'。
  4. 这是一个可能的解决方案:

    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();
    

答案 1 :(得分:0)

在PHP中,有一个类和/或实例化对象中的reserved words self and parent for accessing static methodsparent引用父类的继承方法。

class b extends a
{
    function foo()
    {
        echo parent::bar();
    }
}
编辑:嗯,这不是诀窍......(使用PHP 5.3.5)

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

第二次编辑:哈,如果你在课程__call()中省略了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