我在可选的 PHP 参数上做错了什么



我有以下类:

class MyClass {
    public function __construct($id = 0, $humanIdentifier = '') {
        $this->id = $id;
        $this->humanID = $humanIdentifier;
    }
}

因此,根据我的解释,我应该能够将$id或$humanIdentifier传递给该构造函数,如果我愿意,两者都不能传递或两者兼而有之。 但是,当我调用下面的代码时,我发现它是构造函数参数中的$id被设置为 hello world,而不是$humanIdentifier,尽管我在调用构造函数时指定了$humanIdentifier。谁能看出我哪里出了问题?

$o = new MyClass($humanIdentifier='hello world');

编辑:从 PHP8 开始,现在支持命名参数。在撰写本文时,情况并非如此。

PHP 不支持命名参数,它将根据您传递参数的顺序设置值。

在您的情况下,您传递的不是$humanIdentifier,而是表达式 $humanIdentifier='hello world' 的结果,稍后$this->id将设置为该表达式。

我知道在PHP中模仿命名参数的唯一方法是数组。所以你可以做(在 PHP7 中(:

public function __construct(array $config)
{
    $this->id = $config['id'] ?? 0;
    $this->humanId = $config['humanId'] ?? '';
}

谁能看出我哪里出了问题?

的,您认为这些是命名参数。他们不是。它们是位置参数。所以你会这样称呼它:

new MyClass(0, 'hello world')

过去曾建议添加对命名参数的支持,但被拒绝了。提出了一个更新的RFC,但它仍有待完善和实施。

您需要重载构造函数,但 php 没有内置功能,但在文档中有一个很好的解决方法:

http://php.net/manual/en/language.oop5.decon.php#Hcom99903

另外,这里有一个讨论,为什么这可能是一个坏主意:为什么我不能在 PHP 中重载构造函数?

就像另一个答案所说,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将在那里。 我相信你可以想出一些花哨的迭代来完成这个,如果有足够的参数让它值得。

你不能通过这种方式创建新的类对象:

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

相关内容

最新更新