PHP OOP:为什么 self::$$property[$key] 不起作用


PHP OOP: why does self::$$property[$key] not work?

有没有办法在没有foreach循环(否则未更改)的情况下实现以下PHP类?

<?php
class foo {
  private static $_thing = array(
    'kee' => 'valyu'
  );
  public static function fetch($property, $key = '') {
    if (property_exists('foo', $property)) {
      if ($key == '') return self::$$property;
      else {
        # i cannot seem to do self::$$property[$key].
        foreach (self::$$property as $_key => $_value) {
          if ($_key == $key) return $_value;
        }
      }
    }
    return false;
  }
}
var_dump(foo::fetch('bad'));            # null
var_dump(foo::fetch('_thing'));         # array(1) { ... }
var_dump(foo::fetch('_thing', 'bad'));  # null
var_dump(foo::fetch('_thing', 'kee'));  # string(5) "valyu"
?>

self::$$property[$key]让我"访问未声明的静态属性:foo::$x"(x字符串值 $key 中的第一个字符)。

这只是

php 解析器的一个怪癖,似乎没有办法用语法告诉解析器您希望先解析变量变量,然后在一行中使用其结果的[]而不是先使用$property[$key]

但是,如果您将其一分为二,它将正常工作:

class foo {
  private static $_thing = array(
    'kee' => 'valyu'
  );  
  public static function fetch($property, $key = '') {
   if (property_exists('foo', $property)) {
      if ($key == '') { 
        return self::$$property;
      } else {
        $prop = self::$$property; // move the result to temporary variable, first part of $$property[$key]
        if (array_key_exists($key, $prop)) { //isset will return false if the key is in fact set to null
            return $prop[$key]; // use it, second part of $$property[$key]
        }   
      }   
    }   
    return null;
  }   
}   
var_dump(foo::fetch('bad'));            // null
var_dump(foo::fetch('_thing'));         // array(1) { ... }
var_dump(foo::fetch('_thing', 'bad'));  // null
var_dump(foo::fetch('_thing', 'kee'));  // string(5) "valyu"

更新:

正如 Dan 善意地指出的那样,{}语法可用于消除解析器的意图,如下所示:

public static function fetch($property, $key = '') {
  if (property_exists('foo', $property)) {
    if ($key == '') {
      return self::$$property;
    } else if (array_key_exists($key, self::${$property})) {
      return self::${$property}[$key];
    }   
  }   
  return null;
}

我还将最后一个返回从 false 更改为 null,以便它与您的示例的评论相匹配。