PHP:如何将子类__construct()参数传递给parent :: __ construct()?

non*_*one 36 php inheritance constructor

我有一个PHP类,如下所示:

class ParentClass {
    function __construct($arg) {
        // Initialize a/some variable(s) based on $arg
    }
}
Run Code Online (Sandbox Code Playgroud)

它有一个子类,如下:

class ChildClass extends ParentClass {
    function __construct($arg) {
        // Let the parent handle construction. 
        parent::__construct($arg); 
    }
}
Run Code Online (Sandbox Code Playgroud)

如果出于某种原因,ParentClass需要更改为接受多个可选参数,我希望我的Child类提供"以防万一",该怎么办?除非我重新编写ChildClass代码,否则它只会将一个参数带到构造函数中,并且只传递那个参数.

这是如此罕见或如此糟糕的做法,通常的情况是,ChildClass不需要从具有不同参数的ParentClass继承?

从本质上讲,我在Python中已经看到,你可以将一个潜在未知数量的参数传递给函数,somefunction(*args)其中'args'是某种数组/可迭代的.PHP中是否存在类似的内容?或者我应该在继续之前重构这些类?

And*_*ndy 41

这可以在PHP> = 5.6中完成,而无需call_user_func_array()使用...(splat)运算符:

public function __construct()
{
    parent::__construct(...func_get_args());
}
Run Code Online (Sandbox Code Playgroud)

  • @miken32你可以这样做,但你失去了输入参数的能力。 (2认同)

sou*_*rge 32

在PHP中有这样的东西,虽然有点冗长:

$args = func_get_args();
call_user_func_array(array($this, 'parent::__construct'), $args);
Run Code Online (Sandbox Code Playgroud)

  • 在5.5(也许更早)你可以做:`call_user_func_array('parent :: __ construct',func_get_args());`; (8认同)
  • @ ogc-nick我只是在版本5.2到5.6上试了一下并成功了. (2认同)

小智 10

如果你得到php嵌套限制错误,试试这个:

$args = func_get_args();
call_user_func_array(array('parent', '__construct'), $args);
Run Code Online (Sandbox Code Playgroud)

  • 这项工作并没有引入无限循环. (2认同)

zst*_*ate 6

我的做法(在 PHP 7.1 中测试):

class ParentClass {
    public function __construct(...$args) {
        print 'Parent: ' . count($args) . PHP_EOL;
    }
}

class ChildClass extends ParentClass {
    public function __construct(...$args) {
        parent::__construct(...$args);
        print 'Child: ' . count($args). PHP_EOL;
    }
}

$child = new ChildClass(1, 2, 3, new stdClass);

//Output: 
//Parent: 4
//Child: 4
Run Code Online (Sandbox Code Playgroud)

测试一下https://3v4l.org/csJ68

在这种情况下,父级和子级具有相同的构造函数签名。如果您想在父构造函数中解压缩参数,它也适用:

class ParentClass {
    public function __construct($a, $b, $c, $d = null) {
        print 'Parent: ' . $a .  $b .  $c . PHP_EOL;
    }
}

class ChildClass extends ParentClass {
    public function __construct(...$args) {
        parent::__construct(...$args);
    }
}

$child = new ChildClass(1, 2, 3);

//Output: Parent: 123
Run Code Online (Sandbox Code Playgroud)

测试一下https://3v4l.org/JGE1A

还值得注意的是,在 PHP >= 5.6 中,您可以强制可变参数函数的类型(PHP >= 7 中的标量类型):

class ParentClass {
    public function __construct(DateTime ...$args) {
        //Do something
    }
}
Run Code Online (Sandbox Code Playgroud)