PHP multiple function return types String|int

2.5k Views Asked by At

I've come across a bit unusual scenario where my function returns multiple types string or integer. I'm trying to declare return types. Could anyone please suggest me the best practice here to declare.

I'm aware that null or other type I can use something like this

/**
 * Get the result status as a formatted string
 * @return string|null formatted status
 */
public function abStatus() : ?string {

but my function is like below returns string or integer

/**
 * Get the score for this action
 * @return string|int
 */
public function getAlphaScore() {
    if ($this->type != self::TYPE_ACTION) {
        return 0;
    }
    if (empty($this->action->status < self::STATUS_IMPORTED) {
        return 'U';
    }

    return ActionCalculator::actionScore($this->action->score);//returns integer here
}

Now, I'm wondering how should I declare my function with return types

public function getAlphaScore() : string {

or

 public function getAlphaScore() : int {

also I want to know ideas/suggestions/best practices on a situation like this where multiple return types will be returned

/**
 * @param $compareAction
 * @return float|int|null
 */
3

There are 3 best solutions below

0
Mjh On

You don't declare the return type then.

It's either string or int, you can't have both.

That's where PHP's weak typing kicks in.

0
Dan On

"Best" practice would say it's best to have a consistent return type. There's no way to define strict return type when you don't have a strict return type. So you're in this situation kind of by design.

It's probably best to look at why you have these different return types. Then you have some options.

  1. I'm not totally clear on the logic, but is it more relevant to throw an exception instead of returning 0?

  2. Not a great solution, but if the first if returned null instead of 0 you could use nullable return type like ?string

  3. Does it make sense to have two functions? getAlphaScoreAsInteger getAlphaScoreAsString. Depending on what you're trying to do of course

0
PCaligari On

I would suggest best practice is to only return one type from a method or function and not mixed types.

Assuming the score is either an integer or a string representation of the integer ( 123 or "123" ) then decide which type you want it to be a use type casting to enforce it.

As you are returning 'U' then I would suggest casting to string. You could add in a check using ctype_digit to ensure your string only contains number characters before returning it and throw an exception if not.

Alternatively return null instead of 'U' and use the ?int annotation. A strict check on the return value would allow you to turn null into 'U'.