Null & Null-Safe Operators

Missing data is everywhere — absent array keys, unset properties, optional objects. PHP gives you three sharp tools for handling null gracefully: ?? for defaults, ??= for lazy assignment, and ?-> for safe object chains.

Learn Null & Null-Safe Operators in our free PHP course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick recall.

Part of the free Php course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

What You'll Learn in This Lesson

1️⃣ What null Really Is

null is the type that means "no value". A variable is null when you assign null , when a function returns nothing, or when you read an array key or property that doesn't exist. Test for it with === null or is_null() — and don't confuse "is null" with "is falsy": 0 and "" are falsy but are not null.

2️⃣ The ?? Operator

The null coalescing operator ?? returns the left side unless it's null or undefined, in which case it returns the right side — and it never emits an "undefined key" warning. It also chains , walking left to right until it finds a non-null value.

3️⃣ The ??= Operator

The null coalescing assignment operator ??= writes a value only if the target is currently null or unset. It's the tidy shorthand for "set this default if nothing's there yet", and it's great for lazy initialisation and caching.

4️⃣ ?? vs ?: — Null vs Falsy

This is the distinction that trips people up. ?? only reacts to null ; the short ternary ?: (the "Elvis" operator) reacts to anything falsy . For a value of 0 or "" , the two behave completely differently — choose deliberately.

5️⃣ The Nullsafe Operator ?->

Added in PHP 8, the nullsafe operator ?-> reads a property or calls a method only if the object isn't null; if it is, the whole chain evaluates to null instead of throwing. It replaces piles of nested isset() checks for optional object graphs, and pairs perfectly with ?? for a final default.

Now you try. Fill the ___ blanks with ?? or ??= .

These scrambled lines should pick a display name and default a role. Put them in the order that prints Sam (member) .

Create the array first, then derive $name and $role from it, then echo. The chain $user['nick'] ?? $user['name'] skips the null nickname and lands on "Sam", and the missing role key falls back to "member". Output: Sam (member) .

Predict the output before revealing each answer.

Prints 0 . ?? only replaces null, and 0 is not null. With ?: instead, it would print none .

Prints 5 . The first ??= sets $x to 5 because it was null; the second is skipped because $x is no longer null.

Evaluates to n/a . The ?-> short-circuits the null object to null (no error), then ?? supplies the default.

📋 Quick Reference — Null Operators

Write it yourself, run it on onecompiler.com/php or your own machine, then check against the expected output in the comments.

Practice quiz

What does echo $count ?? 'none'; print when $count = 0?

  • none
  • (empty string)
  • 0
  • null

Answer: 0. ?? only replaces null or undefined. 0 is not null, so it is kept.

What does echo $count ?: 'none'; print when $count = 0?

  • none
  • 0
  • false
  • null

Answer: none. The ?: (Elvis) operator reacts to any falsy value, and 0 is falsy, so it is replaced.

After $x = null; $x ??= 5; $x ??= 9; what is $x?

  • 9
  • null
  • 14
  • 5

Answer: 5. The first ??= sets $x to 5 because it was null; the second is skipped because $x is no longer null.

What is the result of null ?? null ?? 'third' ?? 'fourth'?

  • 'fourth'
  • 'third'
  • null
  • An error

Answer: 'third'. ?? chains left to right and stops at the first non-null value, which is 'third'.

If $user->address is null, what is $user->address?->city ?? 'n/a'?

  • 'n/a'
  • null
  • An 'attempt to read property on null' error
  • 'city'

Answer: 'n/a'. ?-> short-circuits the null object to null without error, then ?? supplies the default 'n/a'.

Which expression is true?

  • 0 === null
  • "" === null
  • null === null
  • "0" === null

Answer: null === null. null === null is true. 0 and "" are falsy but are NOT null.

What does the ??= operator do?

  • Always assigns the right side
  • Assigns the right side only if the left side is null or unset
  • Assigns only if the left side is falsy
  • Compares two values for null

Answer: Assigns the right side only if the left side is null or unset. ??= is null coalescing assignment: $x ??= $d is shorthand for $x = $x ?? $d.

What does $config['lang'] ?? 'en' do when the 'lang' key is missing?

  • Returns 'en' but emits an 'Undefined array key' warning
  • Throws a TypeError
  • Returns null
  • Returns 'en' with no warning

Answer: Returns 'en' with no warning. ?? is null-and-undefined safe: it returns the default and never emits the undefined-key warning.

Which statement about the nullsafe operator ?-> is true?

  • You can write $obj?->prop = 1 to assign safely
  • It is read-only — you cannot assign through it
  • It throws when the object is null
  • It only works on arrays

Answer: It is read-only — you cannot assign through it. Nullsafe is read-only; $obj?->prop = 1 is not allowed. It safely reads or calls when the object is non-null.

When should you reach for ?? rather than ?:?

  • When you mean 'empty or falsy'
  • When comparing strings
  • When you mean 'missing or null'
  • When the value is always 0

Answer: When you mean 'missing or null'. Rule of thumb: ?? for 'missing/null', ?: for 'empty/falsy'. They differ around values like 0 and "".