Is There a "Nullsafe Operator" in PHP

Is there a nullsafe operator in PHP?

From PHP 8, you are able to use the null safe operator which combined with the null coalescing operator allows you to write code like:

echo $data->getMyObject()?->getName() ?? '';

By using ?-> instead of -> the chain of operators is terminated and the result will be null.

The operators that "look inside an object" are considered part of the chain.

  • Array access ([])
  • Property access (->)
  • Nullsafe property access (?->)
  • Static property access (::)
  • Method call (->)
  • Nullsafe method call (?->)
  • Static method call (::)

e.g. for the code:

$string = $data?->getObject()->getName() . " after";

if $data is null, that code would be equivalent to:

$string = null . " after";

As the string concatenation operator is not part of the 'chain' and so isn't short-circuited.

How can I use Nullsafe operator in PHP

PHP 7

$country =  null;

if ($session !== null) {
$user = $session->user;

if ($user !== null) {
$address = $user->getAddress();

if ($address !== null) {
$country = $address->country;
}
}
}

PHP 8

$country = $session?->user?->getAddress()?->country;

Instead of null check conditions, you can now use a chain of calls with the new nullsafe operator. When the evaluation of one element in the chain fails, the execution of the entire chain aborts and the entire chain evaluates to null.

source: https://www.php.net/releases/8.0/en.php

How does null safe operator works in php 8?

What it does is surely explained in the blog post you found it mentioned in.

How it works is best explained by a simple bytecode dump:

 L3    #0     JMP_NULL                $null                J5                   @1
L3 #1 FETCH_OBJ_R $null "optional" ~0
L3 #2 JMP_NULL ~0 J5 @1
L3 #3 INIT_METHOD_CALL ~0 "maybenull"
L3 #4 DO_FCALL
L4 #5 RETURN<-1> 1

Any occurence of ?-> is represented by an attribute fetch or method call, but preceded with JMP_NULL, that would simply skip the remainder of the expression.

Difference Between null coalescing operator (??) and nullsafe operator (?-) introduced in PHP 8

Null coalescing operator (??) work as an if statement it takes two values if first is null then it is replaced by second.

$a = null;
$b = $a ?? 'B';

Here $b will get the value B as $a is null;

In PHP8, NullSafe Operator (?->) was introduced will gives option of chaining the call from one function to other. As per documentation here: (https://www.php.net/releases/8.0/en.php#nullsafe-operator)

Instead of null check conditions, you can now use a chain of calls with the new nullsafe operator. When the evaluation of one element in the chain fails, the execution of the entire chain aborts and the entire chain evaluates to null.

Here is the example from documentation:


$country = null;

if ($session !== null) {
$user = $session->user;

if ($user !== null) {
$address = $user->getAddress();

if ($address !== null) {
$country = $address->country;
}
}
}

But in PHP8 you can simply do this:


$country = $session?->user?->getAddress()?->country;

So the working of both operators is significantly different.

Using php null safe and null coalescing operators with an array containing anonymous functions

Your attempt is using the null-coalescing operator on the result of calling the function. So it won't prevent the undefined array index or calling the null function that results.

From the Nullsafe Operator RFC

Future Scope

...

A nullsafe function call syntax ($callableOrNull?()) is also outside of scope for this RFC.

So this is something that may be addressed in the future, but it's not in the existing design.

null safe the laravel relationship object

You can set default object adding withDefault to your relationship for example:

public function profile()
{
return $this->belongsTo(Profile::class)->withDefault();
}

or

public function profile()
{
return $this->belongsTo(Profile::class)->withDefault(['name' => 'No profile']);
}

Why am I getting Undefined property: stdClass:: with php 8 nullsafe operator

You seem to have a slight misunderstanding of what the nullsafe operator does.

If $reference was null, then $reference?->first_name would return null with no warning, but since $reference is actually an object, ?-> just functions like a normal object operator, hence the undefined property warning.

Check method in method exists or is not null

In PHP 8.0, there is a new "nullsafe operator", spelled ?-> for exactly this purpose: it calls the method only if the value is not null.

The only part if can't do is the extra check on ->count(), but as long as ->first() returns null rather than an error on an empty set, this would work:

$imageUrl = $item?->getProduct()?->getMedia()?->first()?->getMedia()?->getUrl();

Unless and until you can upgrade to PHP 8, your best bet will be to look for ways to improve the API to avoid this problem in the first place. In line with the Law of Demeter, you could define additional methods so that you could write this:

$imageUrl = $item->hasProductMedia() ? $item->getProductMedia()->first()->getUrl() : null;

The implementation of hasProductMedia() and getProductMedia() still need those checks, but they're hidden away rather than written each time you need to access it.

Another approach is the "Null Object Pattern" (hat tip to Markus Zeller for mentioning this in comments). Instead of returning null, each method returns a special "empty object" satisfying the correct interface.

So $item->getProduct() would never return null, but might return a NullProduct; calling getMedia() on that, or any product without any media, would return an EmptyMediaList; and so on. Eventually, you'd call getUrl() on a NullMediaItem, and it would give you a null value.



Related Topics



Leave a reply



Submit