如何在PHP类中扩展静态继承数组

时间:2017-12-29 16:34:26

标签: php class static

假设我有一个静态数组,我想在子类中添加更多值。由于PHP没有静态构造函数,我真的不知道如何以干净的方式实现这一点(我绝对不想在类定义下添加任何内容而无法更改自动加载器)

这是我想要达到的目标(显然不起作用)

class Parent{
    public static $meta = [1,2,3];
}

class Child extends Parent{
    public static $meta = array_merge(parent::$meta,[4,5]);

}

3 个答案:

答案 0 :(得分:1)

您正在重新定义子类中的属性,这是不推荐的。您可以查看here替代方案

此外,父类不是类的允许名称。解决方案是实现返回属性的静态方法。喜欢这个

class ParentClass{
    public static $meta = [1,2,3];

    public static function getMeta() {
        return self::$meta;
    }
}

class Child extends ParentClass{
    public static function getMeta() {
        return array_merge(parent::getMeta(),[4,5]);
    }
}

var_dump(Child::getMeta());

结果是

array(5) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
  [3]=>
  int(4)
  [4]=>
  int(5)
}

您可以在此处查看此内容:https://3v4l.org/v8Mtm

希望得到这个帮助。

答案 1 :(得分:1)

在课堂内使用vars是不可能的。相反,我建议通过getter方法为var提供acccess。除此之外,我建议保护静态var,以防止从外部进行不必要的访问。

使用后期静态绑定,您可以在父类中提供静态函数,该函数将自己的var与来自继承类的变量合并。

class A {
    protected static $meta = [1,2,3];

    public static function getMeta() {
        if (__CLASS__ == static::class) {
            return self::$meta;
        }
        return array_merge(self::$meta, static::$meta);
    }
}

class B extends A {
    protected static $meta = [4,5];
}

var_dump(B::getMeta());

__CLASS__ == static::class的比较仅适用于此示例 - 如果您使用辅助数组并且只想添加新选项,则可以忽略它并使用简单的return self::$meta + static::$meta;

请记住,这仅适用于一级继承。如果您在子类中需要一系列新的$ meta vars,那么您也会覆盖子类中的getMeta方法。

答案 2 :(得分:0)

我可以想象这样做的唯一方法(不使用构造函数或添加类定义)是使用如此的define consts;

/* FOO CLASS FILE */
define('FOO_META', [1, 2, 3]);

class Foo{
    public static $meta = FOO_META;
}

/* BAR CLASS FILE */
define('BAR_META', array_merge(FOO_META, [4, 5, 6]));

class Bar extends Foo{
    public static $meta = BAR_META;
}

echo 'Foo-Meta = ' . implode(', ', Foo::$meta) . '<br>';
echo 'Bar-Meta = ' . implode(', ', Bar::$meta) . '<br>';

类属性只能在类定义中指定const值。您将需要使用构造函数(或其他一些方法)动态执行此操作。如果您使用上述方法,我建议使用如下命名空间:

define('foo\META', [1, 2, 3]);
define('bar\META', array_merge(foo\META, [4, 5, 6]));

编辑:如果这些类只包含这一个属性,为什么不单独使用这些类?它们本质上是相同的,没有额外的开销。