PHP:如何将子类 __construct() 参数传递给 parent::__construct()?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1603469/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP: How to Pass child class __construct() arguments to parent::__construct()?
提问by none
I have a class in PHP like so:
我在 PHP 中有一个类,如下所示:
class ParentClass {
function __construct($arg) {
// Initialize a/some variable(s) based on $arg
}
}
It has a child class, as such:
它有一个子类,如下所示:
class ChildClass extends ParentClass {
function __construct($arg) {
// Let the parent handle construction.
parent::__construct($arg);
}
}
What if, for some reason, the ParentClass needs to change to take more than one optional argument, which I would like my Child class to provide "just in case"? Unless I re-code the ChildClass, it will only ever take the one argument to the constructor, and will only ever pass that one argument.
如果出于某种原因,ParentClass 需要更改以采用多个可选参数,我希望我的 Child 类“以防万一”提供该参数怎么办?除非我重新编码 ChildClass,否则它只会将一个参数传递给构造函数,并且只会传递那个参数。
Is this so rare or such a bad practice that the usual case is that a ChildClass wouldn't need to be inheriting from a ParentClass that takes different arguments?
这是罕见的还是糟糕的做法,以至于通常的情况是 ChildClass 不需要从采用不同参数的 ParentClass 继承?
Essentially, I've seen in Python where you can pass a potentially unknown number of arguments to a function via somefunction(*args)where 'args' is an array/iterable of some kind. Does something like this exist in PHP?Or should I refactor these classes before proceeding?
本质上,我在 Python 中看到过,您可以通过somefunction(*args)其中“args”是某种数组/可迭代对象将潜在未知数量的参数传递给函数。PHP中是否存在这样的东西?或者我应该在继续之前重构这些类?
采纳答案by soulmerge
There is something like this in php, though a bit verbose:
php中有这样的东西,虽然有点冗长:
$args = func_get_args();
call_user_func_array(array($this, 'parent::__construct'), $args);
回答by Andy
This can be done in PHP >= 5.6 without call_user_func_array()by using the ...(splat) operator:
这可以在 PHP >= 5.6 中完成,无需call_user_func_array()使用...(splat) 运算符:
public function __construct()
{
parent::__construct(...func_get_args());
}
回答by petrof
if you get php nested limit error, try this:
如果您收到 php 嵌套限制错误,请尝试以下操作:
$args = func_get_args();
call_user_func_array(array('parent', '__construct'), $args);
回答by zstate
My way of doing it (tested in PHP 7.1):
我的做法(在 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
Test it https://3v4l.org/csJ68
In this case, the parent and the child have the same constructor signature. It also works if you want to unpack your arguments in the parent constructor:
在这种情况下,父级和子级具有相同的构造函数签名。如果您想在父构造函数中解压缩参数,它也适用:
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
Test it https://3v4l.org/JGE1A
It is also worth noticing that in PHP >= 5.6 you can enforce types for variadic functions (scalar types in PHP >= 7):
还值得注意的是,在 PHP >= 5.6 中,您可以强制执行可变参数函数的类型(PHP >= 7 中的标量类型):
class ParentClass {
public function __construct(DateTime ...$args) {
//Do something
}
}
回答by Chris
PHPStorm Inspection suggests to use the argument unpacking feature instead of call_user_func_array(). Apart less magic, the feature is faster. Source: https://wiki.php.net/rfc/argument_unpacking
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());
}
}
回答by David Barnes
Check out these functions on php.net:
在 php.net 上查看这些函数:
func_get_args
func_num_args
Also, if you want to make an optional argument, you can do this:
此外,如果您想创建一个可选参数,您可以这样做:
class ParentClass {
function __construct($arg, $arg2="Default Value") {
// Initialize a/some variable(s) based on $arg
}
}
回答by chaos
Yeah, it's pretty bad practice to make a child class that uses different constructor arguments from the parent. Especially in a language like PHP where it's poorly supported.
是的,创建一个使用与父类不同的构造函数参数的子类是非常糟糕的做法。特别是在像 PHP 这样的语言中,它的支持很差。
Of course, the generic way to pass a set of "whatever arguments we might ever want" in PHP is to pass a single argument consisting of an array of configuration values.
当然,在 PHP 中传递一组“我们可能想要的任何参数”的通用方法是传递由配置值数组组成的单个参数。
回答by Lee Owen
parent::__construct( func_get_args() );

