我有以下课程:
class MyClass {
public function __construct($id = 0, $humanIdentifier = '') {
$this->id = $id;
$this->humanID = $humanIdentifier;
}
}
所以根据我的解释,我应该能够将$ id或$ humanIdentifier传递给该构造函数,如果我想要的话,或者两者都不传递。但是,当我调用下面的代码时,我发现构造函数args中的$ id被设置为hello world而不是$ humanIdentifier,尽管我在调用构造函数时指定了$ humanIdentifier。谁能看到我错在哪里?
$o = new MyClass($humanIdentifier='hello world');
答案 0 :(得分:7)
PHP不支持命名参数,它将根据传递参数的顺序设置值。
在您的情况下,您没有传递$humanIdentifier
,而是表达$humanIdentifier='hello world'
的结果,$this->id
稍后会被设置。
我知道在PHP中模仿命名参数的唯一方法是数组。所以你可以做(在PHP7中):
public function __construct(array $config)
{
$this->id = $config['id'] ?? 0;
$this->humanId = $config['humanId'] ?? '';
}
答案 1 :(得分:2)
谁能看到我哪里出错了?
是的,您认为这些是命名参数。他们不是。它们是位置参数。所以你这样称呼它:
new MyClass(0, 'hello world')
过去曾建议添加对命名参数的支持,rejected。较新的RFC is proposed,但仍有待完善和实施。
答案 2 :(得分:0)
你需要重载构造函数,但php没有内置的功能,但在文档中有一个很好的解决方法:
http://php.net/manual/en/language.oop5.decon.php#Hcom99903
此处还讨论了为什么这可能是一个坏主意:Why can't I overload constructors in PHP?
答案 3 :(得分:0)
class MyClass {
public function __construct($args = array('id' => 0, 'humanIdentifier' => '') {.
// some conditional logic to emulate the default values concept
if(!isset($args['id'])){
$this->id = 0;
}else{
$this->id = $args['id'];
}
if(!isset($args['humanIdentifier'])){
$this->humanID = '';
}else{
$this->humanID = $args['humanIdentifier'];
}
}
}
然后您可以将其称为:
new MyClass(array('humanIdentifier'=>'hello world'));
,默认id
将在那里。如果有足够的参数可以让它值得,我相信你可以想出一些花哨的迭代来实现这个目标。
答案 4 :(得分:-1)
您不能通过这种方式创建新的对象:
$o = new MyClass($humanIdentifier='hello world');
您可以将数组用作__construct
的参数:
class MyClass {
public function __construct(array $arg) {
$this->id = isset($arg['id']) ? $arg['id'] : 0;
$this->humanID = isset($arg['humanID']) ? $arg['humanID'] : 0;
}
}
然后你可以通过这种方式创建类的新对象:
$o = new MyClass(['humanId'=>hello world']);