如何在PHP中检查我是否处于静态上下文中(或不是)?

Jam*_*low 30 php methods static

有什么方法可以检查方法是静态调用还是实例化对象?

Ben*_*ner 57

请尝试以下方法:

class Foo {
   function bar() {
      $static = !(isset($this) && get_class($this) == __CLASS__);
   }
}
Run Code Online (Sandbox Code Playgroud)

来源:seancoates.com通过谷歌

  • mmm ...这不起作用,如果我有一个'baz'类扩展'foo'并从baz'上下文调用函数'bar',因为\ _\_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ $ this)是'baz'. (7认同)
  • 也许做`$ this instanceof __CLASS__`而不是`get_class($ this)== __CLASS__`? (6认同)
  • 这相当偏执..但还是不错的 (2认同)
  • 正如@harald指出的那样,这不可靠.例如,我刚刚发现了一些类似于这样的生产代码:$ foo-> anotherMethod()调用B :: method()调用Foo :: bar().原始的$ foo变量是Foo的一个实例.在这种情况下,$ this引用了$ foo实例.我还没有找到解决这个问题的方法,除了轻描淡写并小心你的代码设计. (2认同)
  • @neubert` $ this instanceof self`正在为我工​​作.`$ this instanceof __CLASS__`引发[致命错误](https://bugs.php.net/bug.php?id=46593)(至少在PHP 5.3中). (2认同)

小智 11

"将它从debug_backtrace()中删除"并不算太多.debug_backtrace()有一个'type'成员,如果一个调用是静态的,那么是'::',如果不是,则是' - >'.所以:

class MyClass {
    public function doStuff() {
        if (self::_isStatic()) {
            // Do it in static context
        } else {
            // Do it in object context
        }
    }

    // This method needs to be declared static because it may be called
    // in static context.
    private static function _isStatic() {
        $backtrace = debug_backtrace();

        // The 0th call is to _isStatic(), so we need to check the next
        // call down the stack.
        return $backtrace[1]['type'] == '::';
    }
}

  • 你确定吗*?`type`包含函数的*type*,它是`static`或者不是; 它不会根据呼叫协议而改变. (3认同)

tro*_*skn 8

检查是否$this已设置将不起作用.

如果从对象内调用静态方法,$this则将其设置为调用者上下文.如果你真的想要这些信息,我想你必须把它挖出来debug_backtrace.但是你为什么要首先需要呢?您有可能以某种方式更改代码的结构,以便您不这样做.


小智 6

我实际上在我的所有脚本上使用这行代码,它运行良好,它可以防止错误.

class B{
      private $a=1;
      private static $static=2;

      function semi_static_function(){//remember,don't declare it static
        if(isset($this) && $this instanceof B)
               return $this->a;
        else 
             return self::$static;
      }
}
Run Code Online (Sandbox Code Playgroud)

使用instanceof不是偏执狂:

如果A类调用类B静态函数$this可能存在于A范围内; 我知道这很乱,但php会这样做.

instanceof 将解决这个问题,并避免与可能实现"半静态"功能的类冲突.

  • 请注意,PHP 7 只是弃用了将非静态方法作为静态调用,将抛出弃用警告。http://php.net/manual/en/migration70.deprecated.php 将来可能会完全删除该功能。 (2认同)