我的可选PHP参数出错了什么?

时间:2018-01-11 12:08:04

标签: php class constructor

我有以下课程:

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');

5 个答案:

答案 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)

像另一个回答说的那样,php不支持命名参数。你可以用以下方法完成类似的事情:

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']);