【问题标题】:Calling static function from instance从实例调用静态函数
【发布时间】:2011-10-08 16:00:02
【问题描述】:

我正在尝试从其子类的成员调用静态魔术函数 (__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

如何让它显示为“静态”?

【问题讨论】:

  • 好像不可能,我找到了这个讨论:allegro.cc/forums/thread/607508/919970.
  • 这里:Interestingly, PHP 5.3.3 gives __callStatic priority, but that behavior was reverted back in PHP 5.3.4.
  • Lazlo Bonin,请记住您在这里处理的是对象继承。即使你认为你有两个类,这实际上是一个。如果你这样做,那一个类不会被静态调用:$b-&gt;foo();。这不是静态函数调用。黑客将改为这样做:$b::foo();。自己试试吧。
  • @hakre:或者b::foo();。

标签: php methods static instance


【解决方案1】:

如果您删除魔术方法“__call”,您的代码将返回“静态”。

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

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

  1. 您正在从非静态上下文调用静态方法。
  2. 方法调用在非静态上下文中,因此 PHP 搜索魔术方法“__call”。
  3. 如果魔法方法“_call”存在,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();

【讨论】:

  • +1 for “如果你删除魔法方法'__call',你的代码将返回'static'。”和很好的解释。
【解决方案2】:

在 PHP 中有来自类和/或实例化对象的 reserved words self and parent for accessing static methods。 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

【讨论】:

  • 替换为echo self::bar();,仍然显示“instance”。
  • 嗯,是的,但是我在我的设计中有一个 __call 方法,我需要。
猜你喜欢
  • 2010-10-16
  • 1970-01-01
  • 1970-01-01
  • 2013-03-05
  • 1970-01-01
  • 1970-01-01
  • 2011-05-08
  • 2019-11-02
  • 1970-01-01
相关资源
最近更新 更多