PHP:如何将子类_construct()参数传递给父::_construct()?

PHP:如何将子类_construct()参数传递给父::_construct()?,php,inheritance,constructor,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 co

我有一个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需要更改以接受多个可选参数,我希望我的子类提供“以防万一”的参数,该怎么办?除非我对ChildClass重新编码,否则它将只将一个参数传递给构造函数,并且只传递一个参数

这是如此罕见还是如此糟糕的做法,以至于通常情况下,子类不需要从接受不同参数的父类继承


本质上,我在Python中看到过,可以通过
somefunction(*args)
向函数传递数量可能未知的参数,其中“args”是某种数组/iterablePHP中是否存在类似的内容?或者我应该在继续之前重构这些类

是的,创建使用不同于父类的构造函数参数的子类是非常糟糕的做法。特别是在像PHP这样的语言中,它的支持很差


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

在PHP中有类似的内容,尽管有点冗长:

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

请在php.net上查看以下函数:

func_get_args
func_num_args
此外,如果要生成可选参数,可以执行以下操作:

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

如果出现php嵌套限制错误,请尝试以下操作:

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

这可以在PHP>=5.6中完成,而无需使用以下命令调用\u user\u func\u array():

我的做法(在PHP7.1中测试):

测试一下

在这种情况下,父级和子级具有相同的构造函数签名。 如果您想在父构造函数中解包参数,它也可以工作:

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

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


当然,这里有“神奇容器”代码的味道()。您需要的是一个参数对象()。不幸的是,这个神奇的容器在php应用程序中被广泛使用。OP询问父类添加新构造函数参数的情况。这与在子类中更改参数无关。如果您在子构造函数中有额外的初始化逻辑,因此必须调用父构造函数(这可能会更改其参数列表),则此问题的解决方案将非常有用。Hm不按顺序保留参数(只在第一个参数中将其放入数组)。这会导致PHP 5.4.14In 5.5(可能更早)上出现无限循环您只需执行以下操作:
call_user_func_array('parent::_construct',func_get_args())@ogc nick我刚刚在5.2到5.6版本上成功试用了它。有关如何在PHP5.6及更高版本中不调用
用户函数数组()
的信息,请参阅。但是为什么不使用
\u构造()
来避免调用
函数获取参数()
?例如,
public function_uu-construct(…$args){parent::u-construct(…$args);}
@miken32您可以这样做,但是您失去了键入提示参数的能力。它不能回答以下问题:如何使用动态参数数组调用父构造函数。您不能只执行父项::u构造(func_get_args())
public function __construct()
{
    parent::__construct(...func_get_args());
}
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
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
class ParentClass {
    public function __construct(DateTime ...$args) {
        //Do something
    }
}