【问题标题】:See if a static property exists in a child class from the parent class (late static binding)?查看父类的子类中是否存在静态属性(后期静态绑定)?
【发布时间】:2013-03-07 03:56:10
【问题描述】:

父类中的代码:

foreach(static::$_aReadOnlyDatabaseTables AS $TableName => $aColumns){
  // Do something
}

这在 $_aReadOnlyDatabaseTables 在子类中定义时有效,但在 $_aReadOnlyDatabaseTables 不存在时抛出错误。我需要先检查这个属性是否存在。

我认为应该是这样的:

if(property_exists(static,$_aReadOnlyDatabaseTables)){
   foreach(static::$_aReadOnlyDatabaseTables AS $TableName => $aColumns){
      // Do something
   }
}

但这会引发语法错误,unexpected ',', expecting T_PAAMAYIM_NEKUDOTAYIM。使用$this 代替static 也不起作用,它总是评估为假。

什么是正确的语法?

【问题讨论】:

    标签: php late-static-binding


    【解决方案1】:

    你应该试试这个:

    if(property_exists(get_called_class(), '_aReadOnlyDatabaseTables')) {
       foreach(static::$_aReadOnlyDatabaseTables AS $TableName => $aColumns){
          // Do something
       }
    }
    

    【讨论】:

    • @Nick 在父类中声明数组并在子类中覆盖它可能会更快、更有效。然后你可以跳过属性检查。覆盖将在编译时完成一次,并且不会在每次调用该方法时产生额外的开销。
    • @ColinMorelli,谢谢,我也会这样做,但我目前的目标是检测尚未实现此属性的任何子类。
    【解决方案2】:

    正确的方法是在父类中使用合理的默认值(空数组)初始化值。这样您就可以确定该属性将存在。

    您在一个类中访问的所有内容都应该在您单独使用该类时通过正确定义而可用。

    【讨论】:

    • 一般来说这是一个很好的建议,但它并没有解决所提出的问题。在尝试循环之前测试数组是否存在以及它实际上是一个数组也是一种很好的做法。
    【解决方案3】:

    您应该能够使用get_class() 而不是static 关键字来快速而肮脏地执行此操作:

    if (property_exists(get_class($this), '_aReadOnlyDatabaseTables')) { ... }
    

    【讨论】:

    • $this 不应该在静态方法中可用,我猜 OP 将代码放在他的问题中
    • 我没有在OP中提到,但这是一个实例化的类和一个有问题的非静态方法,访问一个静态属性。
    • 好吧,在这种情况下,$this 参考可用。
    猜你喜欢
    • 2014-09-10
    • 2021-08-26
    • 1970-01-01
    • 2014-01-29
    • 2012-10-15
    • 2013-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多