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

时间:2009-10-21 20:38:31

标签: php inheritance constructor

我有一个PHP类,如下:

class ParentClass {
    function __construct($arg) {
        // Initialize a/some variable(s) based on $arg
    }
}

它有一个子类,如下:

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

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

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

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

8 个答案:

答案 0 :(得分:38)

使用... (splat) operator可以在PHP> = 5.6而不是call_user_func_array()的情况下完成此操作:

public function __construct()
{
    parent::__construct(...func_get_args());
}

答案 1 :(得分:31)

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

$args = func_get_args();
call_user_func_array(array($this, 'parent::__construct'), $args);

答案 2 :(得分:10)

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

$args = func_get_args();
call_user_func_array(array('parent', '__construct'), $args);

答案 3 :(得分:3)

我这样做(在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

测试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

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

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

class ParentClass {
    public function __construct(DateTime ...$args) {
        //Do something
    }
}

答案 4 :(得分:1)

在php.net上查看这些功能:

func_get_args
func_num_args

另外,如果要创建可选参数,可以执行以下操作:

class ParentClass {
    function __construct($arg, $arg2="Default Value") {
        // Initialize a/some variable(s) based on $arg
    }
}

答案 5 :(得分:0)

是的,制作一个使用父节点不同构造函数参数的子类是非常糟糕的做法。特别是像PHP那样支持不好的语言。

当然,在PHP中传递一组“我们可能想要的任何参数”的通用方法是传递一个由一组配置值组成的参数。

答案 6 :(得分:0)

PHPStorm Inspection建议使用参数解包功能而不是call_user_func_array()。除魔术外,此功能更快。 来源:https://wiki.php.net/rfc/argument_unpacking

class ChildClass extends ParentClass {
    function __construct($arg) {
        // Let the parent handle construction. 
        parent::__construct(...func_get_args()); 
    }
}

答案 7 :(得分:-6)

parent::__construct( func_get_args() );