jelly5798
jelly5798

Reputation: 349

What am I doing wrong with my optional PHP arguments?

I have a the following class:

class MyClass {

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

So from my interpretation I should be able to pass either $id or $humanIdentifier to that constructor, neither or both if I wanted. However, when I call the code below I am finding that its the $id in the constructor args being set to hello world and not the $humanIdentifier, despite me specifying the $humanIdentifier when calling the constructor. Can anyone see where I am going wrong?

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

Upvotes: 1

Views: 125

Answers (5)

Mat
Mat

Reputation: 1009

Edit: As of PHP8, named arguments are now supported. This wasn’t the case at the time of this post.

PHP does not support named arguments, it will set the value according to the order in which you pass the parameters.

In your case, you're not passing $humanIdentifier, but the result of the expression $humanIdentifier='hello world', to which $this->id is later set.

The only way I know to mimick named arguments in PHP are arrays. So you could do (in PHP7) :

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

Upvotes: 7

NappingRabbit
NappingRabbit

Reputation: 1918

like another answer said, php does not support named arguments. You can accomplish something similar with:

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

you can then call it like:

new MyClass(array('humanIdentifier'=>'hello world'));

and the default id will be there. I am sure you can come up with some fancy iteration to accomplish this if there are enough parameters to make it worth while.

Upvotes: 0

user3647971
user3647971

Reputation: 1056

You need to overload the constructor, but php does not have built-in functionality for it but there's a great workaround for it in documentation:

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

Also here's a discussion why it might be a bad idea: Why can't I overload constructors in PHP?

Upvotes: 0

Vladimir
Vladimir

Reputation: 1391

You can not create new object of class by this way:

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

You can use array as parameter of __construct:

class MyClass {

    public function __construct(array $arg) {
        $this->id = isset($arg['id']) ? $arg['id'] : 0;
        $this->humanID = isset($arg['humanID']) ? $arg['humanID'] : 0;
    }
}

Then you can create new object of class by this way:

$o = new MyClass(['humanId'=>hello world']);

Upvotes: -1

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230306

Can anyone see where I am going wrong?

Yes, you think these are named parameters. They are not. They are positional parameters. So you'd call it like this:

new MyClass(0, 'hello world')

Adding support for named parameters has been suggested and rejected in the past. A newer RFC is proposed, but it still is to be refined and implemented.

Upvotes: 2

Related Questions