从实例调用静态函数


Calling static function from 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

如何让它显示"静态"?

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

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

我认为在你的代码中发生的是,

  1. 你正在从非静态上下文中调用静态方法。
  2. 方法调用是在非静态上下文中,所以PHP搜索魔术方法'__call'。
  3. PHP触发魔术方法'_调用',如果它存在。或者,如果不存在,它将调用'_callStatic'。

这是一个可能的解决方案:

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

在PHP中,有selfparent保留字用于从类和/或实例化对象中访问静态方法。parent引用从父类继承的方法。

class b extends a
{
    function foo()
    {
        echo parent::bar();
    }
}
(使用PHP 5.3.5)

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

第二次编辑:哈,它只工作,如果你省略a类的__call() -方法。

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