【问题标题】:PHP OOP: why does self::$$property[$key] not work?PHP OOP:为什么 self::$$property[$key] 不起作用?
【发布时间】:2012-08-06 08:00:56
【问题描述】:

有没有办法在没有 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 arrays oop properties getter-setter


    【解决方案1】:

    这只是 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,因此它与您示例的 cmets 匹配。

    【讨论】:

    • 耸耸肩。好吧,至少循环消失了。 (应该在 foreach 之前想到这一点!)非常感谢!
    • Mh.还没有尝试过,但self::${$property}[$x] 也不起作用?此处描述:php.net/manual/en/language.variables.variable.php 不是用于属性,而是用于普通变量。不知道这里的使用是否有区别。
    • 似乎工作正常,我尝试在那里添加{}s,但似乎错过了正确的组合。我已经更新了答案
    • 我似乎也记得尝试过{}。诡异。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多