0

I'm currently passing a value - which might be null - to a function that has a default value for that parameter. I expected that if the parameter is null, it would return the default value. But that does not seem to be the case. Now I was wondering if there is a way to work around this?

I know I can check if the value is null, and don't pass it when it is, but I don't want to have too many if's in my code. I just want a clean way to grab the default value if it's null.

Some extra info: I'm using Laravel framework 8 - maybe some nice functions in Laravel I don't know yet.

Example code:

<?php

class Person {
    private $name;
    
    public function greet(string $greeting = 'Hello')
    {
        return sprintf('%s %s', $greeting, $this->name);
    }
    
    public function setName($name)
    {
        $this->name = $name;
        return $this;
    }
}

$externalInput = null;

$person = (new Person())->setName('Maik');
echo $person->greet($externalInput);

This is just an example code, so don't mind the security issues this might have. That's all taken care off in my real code. This code is just to illustrate the problem I'm having.

7
  • You mean you would like $person->greet(null) to give the same result as $person->greet() & $person->greet('Hello')? Commented Jul 30, 2021 at 11:17
  • Just override the parameter if it is null: if ($greeting === null) .... Commented Jul 30, 2021 at 11:19
  • @ZoliSzabó That's exactly what I want ;) Commented Jul 30, 2021 at 11:20
  • @wayneOS I don't want that, so I'm looking for a different way, but thanks for your answer. Commented Jul 30, 2021 at 11:20
  • 1
    null is not the same as omitting an argument with a default value, so no, you cannot do it at language level. See @Bart's answer below. That's the closest you can get. Commented Jul 30, 2021 at 11:24

4 Answers 4

3

I would recommend using a ternary operator inside greet function like -

public function greet($greeting = null) {
   $greeting = isset($greeting) ? $greeting : 'Hello';
   return sprintf('%s %s', $greeting, $this->name);
}
Sign up to request clarification or add additional context in comments.

Comments

3

Same answer as the others, but a bit shorter (using the Null coalescing operator):

public function greet(?string $greeting = null)
{
    return sprintf('%s %s', $greeting ?? 'Hello', $this->name);
}

Comments

2

Something like this?

public function greet(string $greeting = null){
      return sprintf('%s %s', ($greeting ?: 'Hello') , $this->name);
}

1 Comment

I know I can do it like this, but that's not what I want. I was looking for a different way to do it, but by the looks of the comments there is not way to do it like this. So I will create some extra setters in my class and let those handle it. Thanks for your answer though.
2

I don't think you can do what you want to do. I understand your question but NULL, at least in PHP, is a relatively common and valid value that might be passed around, so it will be treated as a proper value, not as a missing parameter. I gave it a go by unset()tting $externalInput but that gave an expected undefined variable result.

Looking at your comments you probably already know this but the solution is to just do the 'old way', before default param values in PHP were a thing. If 0 or '' are not valid values either, you can make it even nicer by swapping $greeting === null with !$greeting. Note that I've made the $greeting param a nullable string by adding ?.

    public function greet(?string $greeting = null)
    {
        if ($greeting === null) {
            $greeting = 'Hello';
        }
        return sprintf('%s %s', $greeting, $this->name);
    }

Edit:: Named arguments, new in PHP could be a nicer solution as well. Seems like you can pass a splatted array myFunc(...$arr) as long as the key=>vals are paramName=>paramVal pairs. Then you could just filter the entire array and remove all NULL values in one go, rather than needing one of these if(isNull) for each individual argument.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.