静态变量的默认值

时间:2014-12-13 21:52:53

标签: php static traits

是否可以使用Traits为静态变量提供默认值?请考虑以下示例。

  trait Properties {
     public static $properties = [];
  }

  class Base {
     use Properties;
  }
  Base::$properties[0] = 'val1';
  Base::$properties[1] = 'val2';
  Base::$properties[2] = 'val3';

  class Derived extends Base {
     use Properties;
  }
  Derived::$properties[1] = 'changed value';
  Derived::$properties[3] = 'new value';

  var_dump(Base::$properties);
  var_dump(Derived::$properties);

我希望输出类似于

  array (size=3)
    0 => string 'val1' (length=4)
    1 => string 'val2' (length=4)
    2 => string 'val3' (length=4)
  array (size=4)
    0 => string 'val1' (length=4)
    1 => string 'changed value' (length=13)
    2 => string 'val3' (length=4)
    3 => string 'new value' (length=9)

该示例不起作用,因为Base and Properties define the same property ($properties) in the composition of Derived。如果我从use Properties移除Derived,则$propertiesBase的{​​{1}}变量相同,并且任何更改都适用于这两个类。我希望通过在两个课程中加入Derived来解决这个问题。有什么好方法可以实现我想要的吗?我不必使用Properties,我只是认为这可能有所帮助。

1 个答案:

答案 0 :(得分:2)

我建议使用非常简单的面向对象的风格。 它没有特征,但使用方法访问器代替属性访问器:

class Base {
  private static $properties;

  public static function getProperties() {
    if (!isset(self::$properties)) {
      self::$properties = ['val1', 'val2', 'val3']; // use `array('val1', 'val2', 'val3')` with PHP<5.4
    }
    return self::$properties;
  }
}

class Derived extends Base {
  private static $properties; // has nothing to do with parent::$properties! 

  public static function getProperties() {
    if (!isset(self::$properties)) {
      self::$properties = parent::getProperties();
      self::$properties[1] = 'changed value';
      self::$properties[] = 'new value';
    }
    return self::$properties;
  }
}

var_dump(Base::getProperties());
var_dump(Derived::getProperties());

请注意,没有使用方法访问器从外部修改内部数组的风险,并且使用带有memoization的方法几乎没有性能影响。