PHP在对象上下文中使用静态方法

Max*_*bre 14 php static-methods magic-methods

我有以下代码(例如,实际上,这是我的真实代码):

<?php
class Foobar
{
  public static function foo()
  {
    exit('foo');
  }
}
Run Code Online (Sandbox Code Playgroud)

当我运行$foobar = new FooBar; $foobar->foo()它显示foo.

为什么PHP会尝试在对象上下文中使用静态方法?有办法避免这种情况吗?


好吧,你们没有得到我的问题:我知道静态和非静态方法之间的区别以及如何调用它们.这是我的全部意义,如果我打电话$foobar->foo(),为什么PHP会尝试运行静态方法?


注意:我运行PHP 5.4.4,报告错误E_ALL.

Fen*_*ton 19

要调用静态方法,请不要使用:

$foobar = new FooBar;
$foobar->foo()
Run Code Online (Sandbox Code Playgroud)

你打电话

FooBar::foo();
Run Code Online (Sandbox Code Playgroud)

PHP手册说......

将类属性或方法声明为静态可使它们无需实例化类的实现.声明为static的属性无法使用实例化的类对象访问(尽管静态方法可以).

这就是为什么你能够在一个实例上调用该方法的原因,即使这不是你想要做的.

无论是静态调用静态方法还是静态调用实例,都无法$this以静态方法访问.

http://php.net/manual/en/language.oop5.static.php

你可以检查一下你是否处于静态环境中,虽然我会质疑这是否有点过分......

class Foobar
{
  public static function foo()
  {
    $backtrace = debug_backtrace();
    if ($backtrace[1]['type'] == '::') {
      exit('foo');
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

另外一个注意事项 - 我相信该方法总是在静态上下文中执行,即使它是在实例上调用的.如果我错了,我很高兴能够纠正这个问题.

  • 在对象上下文中调用静态函数时,他可能期待错误,所以他的问题是为什么没有错误,而不是如何做错. (3认同)
  • @MaximeFabre这个答案清楚地回答了你的问题. (2认同)
  • "有没有办法避免这种情况?"这也是问题的一部分,即*没有回答. (2认同)

Dan*_*iel 9

由于PHP是一种非常宽容的语言,因此您可以通过重载来阻止此默认行为,__callStatic并且可以使用反射来验证方法范围.

http://php.net/manual/en/language.oop5.overloading.php#object.call

http://php.net/ReflectionClass