2016-04-03 35 views
6

我对found PHP解释器有些奇怪的(对我来说)行为,我不确定在生产中是否安全使用它。通过范围解析运算符调用非静态方法

当我们调用Foo::bar()Foo类没有静态bar方法,但它具有非静态bar方法,解释器将调用非静态barnull(是的,这听起来很可笑)。我期望在这种情况下调用__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时是否还有其他情况?

回答

3

虽然您的上述示例确实有效,但这不是最佳做法。 这是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 
+0

感谢您对文档的引用。我相信在这种情况下必须调用__callStatic。该类不具有这种名称的静态方法。并且文档指出''__callStatic()在静态上下文中调用不可访问的方法时被触发。“# – Kolyunya

+0

@Kolyunya当我尝试在静态(或非静态)内分配/重新分配变量'$ this'时,我注意到了一个有趣的事情)方法是它会返回致命错误'致命错误:无法在/ Path/to/file.php中重新分配$ this。所以,尽管这不是最佳实践,但我无法想象出另一个'isset($ this)'等于'false'的情况。 –

相关问题