访问不使用$this的类父变量


access class parent variable not using $this

class A {
    protected $a = 'aaa';
}
class B extends A {
    protected $a = 'bbb';
    public function __construct(){
       echo parent::$a; // Fatal error: Access to undeclared static property: A::$a in main.php on line 11
    }
}
$b = new B();

我想在类 B 的构造函数中访问类 A 中的$a变量.请注意,$a变量在类 B 中被覆盖。如何访问父::$a?

执行此操作的唯一方法是将$a声明为静态:

protected static $a = 'aaa';

但这将使所有实例的parent::$a值相同。如果你想要单独的值,这是无法做到的,你最好重命名变量,例如一个是$a的,另一个是$b的。

class A {
    protected $a = 'aaa';
}
class B extends A {
    protected $a = 'bbb';
    public function __construct(){
       echo parent::$a; // Fatal error: ...
    }
}
$b = new B();

如何访问家长::$a?

你不能,parent::$a 表示您正在尝试从父类访问静态属性。

而不是这样做,使用构造函数修改$a

class B extends A {
    public function __construct(){
       // do something with $this->a value here;
    }
}

或者,如果您将其重新声明为 B 中的属性,您将始终覆盖$a。

我刚刚阅读了您的评论,所以我现在更好地理解了您的用例。如果您在继承类中添加/合并配置,我建议使用另一种方法,添加一些行为。

正如您在上面确认的那样:

  • A 具有默认配置
  • B 可以选择传入可以更新/添加到默认配置的config

在这种情况下,这样的东西可能适合你:

class A
{
    protected $config = array(
        'foo' => 'foo',
        'bar' => 'bar',
        'baz' => 'baz',
    );
    public function __construct(array $config = array())
    {
        $this->config = array_merge($this->config, $config);
    }
    public function getConfig()
    {
        return $this->config;
    }
}
class B extends A
{
    // implement
}
$b = new B(array(
    'foo' => 'OVERWRITTEN',
    'new' => 'NEW',
));
print_r($b->getConfig());

收益 率:

Array
(
    [foo] => OVERWRITTEN
    [bar] => bar
    [baz] => baz
    [new] => NEW
)

您也可以在直接使用类A时以相同的方式覆盖默认配置。或者,您可以将其实现为setConfig()方法,

而不是在__construct()中实现合并。

希望这对:)有所帮助

编辑

我只想再补充一件事:如果你的config是一个多维数组,你将不得不改变合并数组的方式。乍一看,array_merge_recursive()似乎是显而易见的候选人。然而:

$old = array(
    'foo' => 'foo',
    'bar' => 'bar',
    'baz' => array(
        'baa' => 'baa',
        'boo' => 'boo',
    ),
);
$new = array(
    'foo' => 'FOO',
    'baz' => array(
        'baa' => 'BAA',
    ),
    'new' => 'new'
);
$merge = array_merge_recursive($old, $new);
print_r($merge);

实际产量:

Array
(
    [foo] => Array
        (
            [0] => foo
            [1] => FOO
        )
    [bar] => bar
    [baz] => Array
        (
            [baa] => Array
                (
                    [0] => baa
                    [1] => BAA
                )
            [boo] => boo
        )
    [new] => new
)

可能不是你要找的!请改用array_replace_recursive()

$merge = array_replace_recursive($old, $new);
print_r($merge);

这会产生:

Array
(
    [foo] => FOO
    [bar] => bar
    [baz] => Array
        (
            [baa] => BAA
            [boo] => boo
        )
    [new] => new
)
@Darragh我

让它有点不同,因为我不想改变我的构造函数:

abstract class A
{
    protected $a = array('a' => 1, 'b' => 2);
    public function __construct()
    {
        $this->mixA();
    }
    protected function a()
    {
        return array();
    }
    protected function mixA()
    {
        foreach ($this->a() as $key => $val) {
            $this->a[$key] = $val; // $val can be an array too (in my case it is)
        }
    }
}
class B extends A
{
    protected function a()
    {
        return array(
            'b' => 'new value',
            'c' => 'new variable'
        );
    }
    public function dumpA()
    {
        var_dump($this->a);
    }
}
$b = new B();
$b->dumpA();

所以现在如果我想更改我的默认配置,我只需覆盖 a() 方法。 mixA() 方法可以根据需要扩展。