【问题标题】:Invoking a non-static method via the scope resolution operator通过范围解析运算符调用非静态方法
【发布时间】:2016-07-23 07:43:39
【问题描述】:

我有found PHP 解释器的一些奇怪(对我而言)行为,我不确定在生产中使用它是否安全。

当我们调用Foo::bar() 并且Foo 类没有静态bar 方法但它有非静态bar 方法时,解释器将在null 上调用非静态bar (是的,这听起来很荒谬)。我希望在这种情况下调用__callStatic。但这不是出于某种原因正在发生的事情。

然后我发现了这种行为的一个方便的用法:为类提供具有相同名称的静态和非静态方法,如下所示:

class Foo
{
    public function bar(){
        if (isset($this)) {
            $this->nonStaticBar();
        } else {
            static::staticBar();
        }
    }

    private function nonStaticBar() {
        echo "Non-static\n";
    }

    private static function staticBar() {
        echo "Static\n";
    }
}

(new Foo())->bar(); // Output: "Non-static"
Foo::bar(); // Output: "Static"

是的,我知道,这种方法既不优雅,也不在架构上是错误的。问题是使用这个“功能”是否安全(符合标准)。 isset($this) 可以等于false 是否还有其他情况?

【问题讨论】:

    标签: php methods static-methods


    【解决方案1】:

    虽然您上面的示例确实有效,但这不是最佳实践。 这在 PHP 文档 here 中得到认可,并指出在 PHP 版本 7 之前的版本中,如果启用了 E_STRICT 错误报告,那么它将发出错误:

    Strict Standards: Non-static method Foo::bar() should not be called statically in /Path/to/file.php on line 22
    

    另外,在 PHP 7 及以上版本中,静态调用静态函数已被弃用,执行时会导致以下错误:

    Deprecated:  Non-static method Foo::bar() should not be called statically in /Path/to/file.php on line 22
    

    【讨论】:

    • 感谢您对文档的引用。我相信在这种情况下必须调用__callStatic。该类没有具有此类名称的静态方法。并且文档声明__callStatic() is triggered when invoking inaccessible methods in a static context.
    • @Kolyunya 在尝试在静态(或非静态)方法中分配/重新分配变量 $this 时,我注意到一件有趣的事情,它会返回致命错误 Fatal error: Cannot re-assign $this in /Path/to/file.php。因此,即使这不是最佳实践,我也无法想象isset($this) 等于false 的另一种情况。
    猜你喜欢
    • 2011-10-24
    • 2015-09-14
    • 2013-06-13
    • 2012-04-20
    • 2010-09-09
    • 2020-12-12
    • 2016-04-09
    • 2014-10-05
    • 2015-12-18
    相关资源
    最近更新 更多