2

有没有办法在没有 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字符串值中的第一个字符)。

4

1 回答 1

3

这只是 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;
}

我还将最后一个返回从更改为falsenull以便它与您示例的注释相匹配。

于 2012-08-09T06:18:22.000 回答