【问题标题】:Is there any way to detect the target class in static methods?有没有办法在静态方法中检测目标类?
【发布时间】:2008-09-17 14:34:48
【问题描述】:

下面是一个示例类层次结构和代码。我正在寻找一种方法来确定 'ChildClass1' 或 'ChildClass2' 是否调用了静态方法 whoAmI() 而无需在每个子类中重新实现它。

<?php

abstract class ParentClass {

    public static function whoAmI () {

        // NOT correct, always gives 'ParentClass'
        $class = __CLASS__;

        // NOT correct, always gives 'ParentClass'. 
        // Also very round-about and likely slow.
        $trace = debug_backtrace();
        $class = $trace[0]['class'];

        return $class;
    }
}

class ChildClass1 extends ParentClass {

}

class ChildClass2 extends ParentClass {

}

// Shows 'ParentClass'
// Want to show 'ChildClass1'
print ChildClass1::whoAmI(); 
print "\n";

// Shows 'ParentClass'
// Want to show 'ChildClass2'
print ChildClass2::whoAmI();
print "\n";

【问题讨论】:

    标签: php oop php-5.3 php-5.2


    【解决方案1】:

    我相信你指的是一个已知的 php 错误。 Php 5.3 旨在通过新的后期静态绑定功能解决此问题。

    http://www.colder.ch/news/08-24-2007/28/late-static-bindings-expl.html

    【讨论】:

      【解决方案2】:

      类识别通常是多态性没有被很好理解的症状。

      ChildClass1 和 ChildClass2 的客户端不需要区分它们。

      没有任何地方可以让任何班级询问someObject.whoAmI()

      当你有写if someObject.whoAmI() == 'ChildClass1' { do X(someObject) }的冲动时,你真的应该在ParentClass中添加一个X()方法,并在各种ChildClass中实现各种实现。

      这种“运行时类型识别”几乎总是可以用适当的多态类设计代替。

      【讨论】:

      • @S.Lott 我完全同意,如果在实际代码中使用这种方法将是一个泄漏的抽象。在这种情况下,该方法只是为了提供一个可以理解的示例。我想要确定子类的原因是,我可以利用类层次结构的所有成员共享的静态实例创建方法,但仍然调用适当的子构造函数。
      【解决方案3】:

      既然 PHP 5.3 在野外广泛使用,我想汇总这个问题的答案,以反映最新可用的技术。

      正如其他答案中提到的,PHP 5.3 通过新的 static 关键字引入了 Late Static Binding。此外,还提供了一个新的get_called_class() 函数,该函数只能在类方法(实例或静态)中使用。

      为了确定这个问题中所要求的类,get_called_class() 函数是合适的:

      <?php
      
      abstract class ParentClass {
      
          public static function whoAmI () {
              return get_called_class();
          }
      
      }
      
      class ChildClass1 extends ParentClass {
      
      }
      
      class ChildClass2 extends ParentClass {
      
      }
      
      // Shows 'ChildClass1'
      print ChildClass1::whoAmI(); 
      print "\n";
      
      // Shows 'ChildClass2'
      print ChildClass2::whoAmI();
      print "\n";
      

      user contributed notes for get_called_class() 包括一些示例实现,这些示例实现也应该在 PHP 5.2 中使用debug_backtrace()

      【讨论】:

        【解决方案4】:

        从 PHP 5.3 开始,可以使用 static keyword,但目前还不行。

        【讨论】:

          【解决方案5】:

          没有。等待 PHP 5.3。

          【讨论】:

            猜你喜欢
            • 2013-11-28
            • 2013-04-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-08-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多