6

I am often in a situation when the variable can be object or null.

When I put data into the database I have to stick with something like this:

// @var User|null $user $data['id_user'] = $user!==null ? $user->getId() : null; 

Is there any way to shorthen this? I am aware of ??, but this is somewhat opposite.

I am using PHP 7.1.

7
  • stackoverflow.com/q/1993409/534109 - you're looking for the elvis operator Commented Jan 18, 2019 at 16:35
  • That won't exactly work in this case though will it? The Elvis operator would be equivalent to $user ? $user : null; (so $user will be assigned rather than $user->getId()) - and you don't want to do $user->getId() ?: null in case the $user object itself is null (thus calling a method on null)... uh huh huh. Thankyouverymuch. Commented Jan 18, 2019 at 16:39
  • Elvis operator will also generate E_NOTICE if $user is undefined. Commented Jan 18, 2019 at 16:42
  • Actually, your existing code generates E_NOTICE as well, you should probably use something like: isset($user) ? $user->getId() : null; Commented Jan 18, 2019 at 16:48
  • ^ or for the super-cautious a mix of isset(), is_object() and method_exists() ... O_o ... Barmar's solution/hack (depending on perspective) is looking better by the minute. Commented Jan 18, 2019 at 16:52

3 Answers 3

1

As of PHP 8, there is the nullsafe operator ?->. With it you could refactor your code like this:

// @var User|null $user $data['id_user'] = $user?->getId(); 

Prior to PHP 8, you could utilize automatic bool converting to take advantage of the fact that, when converting to bool, null is considered false, but other objects are not (except apparently SimpleXML objects created from empty tags are also considered false). So you could shorten your example to the following:

// @var User|null $user $data['id_user'] = $user ? $user->getId() : null; 

However, this might be less readable since the ? might imply to some people you are working with a bool to begin with, or it could make the reader have to think about how null gets converted to bool. Your original code is more explicit, and thus potentially more readable. In order to make brains work less hard, I often at least consider avoiding using "not equals" whenever possible, and just go with a straight "equals". So you could refactor your code to be like this:

// @var User|null $user $data['id_user'] = $user === null ? null : $user->getId(); 

In this particular case, I think that trick (avoiding "not equals") works fairly well, but sometimes counterintuitively, the code is still more naturally readable to just use a "not equals" anyways.

Sign up to request clarification or add additional context in comments.

Comments

0

If you define a __toString() class in your user object, and have that return the id, then you can use the null coalesce operator:

class User { public function __toString() { return (string) $this->getId(); } } $data['id_user'] = $user ?? null; 

This will not generate any warnings either.

However, it doesn't help too much if you have more than one field you want to do this with.

Comments

-3

I don't think there's an operator that does precisely that.

The closest is the @ error-suppression operator:

$data['id_user'] = @$user->getId(); 

If $user->getId() gets an error, the error message is suppressed and the value is null.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.