Named Arguments and the Nullsafe Operator
PHP 8.0 introduced two small but high-leverage syntax features that meaningfully improve everyday code readability and safety: named arguments, which let a caller specify which parameter each value goes to by name instead of relying purely on position, and the nullsafe operator (?->), which collapses a chain of null checks into a single expression. Both features reduce boilerplate and reduce the chance of subtle bugs — named arguments prevent accidentally swapping two same-typed positional arguments, and the nullsafe operator prevents the classic 'call to a member function on null' fatal error when traversing optional relationships.
Cricket analogy: Naming arguments like setScore(runs: 45, balls: 30) prevents a scorer from accidentally swapping runs and balls when both are integers; the nullsafe operator $team?->captain?->name prevents a fatal error when querying a team that might not have an assigned captain yet.
Named arguments
A named argument is passed as parameterName: value at the call site, using the exact parameter name from the function's signature. Named and positional arguments can be mixed in a single call, provided all positional arguments come first. The biggest practical benefit is with functions that have several optional parameters with default values — instead of passing every intermediate default explicitly and in order just to reach the one you need to override, you name only the parameters you actually want to set, in any order, which also makes call sites self-documenting without needing to check the function signature.
Cricket analogy: Calling bookNet(coach: 'Rahul', duration: 60) names only the parameters you want, skipping every intermediate default like venue or equipment; a booking function with five optional parameters becomes self-documenting at the call site instead of forcing you to check the signature.
<?php
declare(strict_types=1);
function createUser(
string $name,
string $email,
bool $isAdmin = false,
?string $locale = 'en',
bool $sendWelcomeEmail = true,
): array {
return compact('name', 'email', 'isAdmin', 'locale', 'sendWelcomeEmail');
}
// Positional + named mix: skip locale and sendWelcomeEmail defaults cleanly
$user = createUser('Grace Hopper', 'grace@example.com', isAdmin: true);
// Fully named, order doesn't matter
$other = createUser(
email: 'ada@example.com',
name: 'Ada Lovelace',
locale: 'en-GB',
);The nullsafe operator ?->
Before PHP 8.0, safely reading a deeply nested, possibly-null chain of properties or method calls required verbose, repeated isset()/?? checks or nested if statements. The nullsafe operator ?-> replaces -> at any link in the chain: if the value on the left of ?-> is null, the entire rest of the chain short-circuits and evaluates to null immediately, without attempting to call a method or read a property on null and without triggering a fatal error. Only one ?-> is needed per potentially-null link; once a ?-> short-circuits, PHP does not evaluate any subsequent -> or ?-> in the same chain.
Cricket analogy: Before nullsafe, checking $team->captain->stats->average required nested isset() checks at each link; ?-> replaces -> so if $team->captain is null, the whole chain short-circuits to null immediately, without throwing a fatal error trying to read stats off a nonexistent captain.
<?php
declare(strict_types=1);
final class Address { public function __construct(public readonly string $city) {} }
final class Profile { public function __construct(public readonly ?Address $address = null) {} }
final class User { public function __construct(public readonly ?Profile $profile = null) {} }
function cityOf(User $user): ?string
{
// Old way: nested isset/if checks at every level
// New way: one operator handles the whole chain
return $user->profile?->address?->city;
}
$userWithNoProfile = new User();
var_dump(cityOf($userWithNoProfile)); // NULL, no fatal errorNamed arguments and the nullsafe operator combine nicely with constructor property promotion and nullable typed properties — a common modern PHP pattern is public function __construct(public readonly ?Address $address = null) {} paired with ?-> chains at the call site to read optional nested data safely and with self-documenting constructor calls.
The nullsafe operator only guards against null — it does not suppress other errors, such as calling a genuinely undefined method on a non-null object, which still throws a normal fatal Error. Also, ?-> cannot be used on the left-hand side of an assignment (e.g. $user?->profile = $x; is not valid) since assignment requires a definite target.
- Named arguments use
paramName: valuesyntax and can be mixed with positional arguments as long as positional ones come first. - Named arguments let callers skip optional parameters with defaults instead of passing every intermediate default in order.
- The nullsafe operator
?->short-circuits an entire chain tonullthe moment any link evaluates to null. - Once
?->short-circuits, no further->/?->calls later in the same chain are evaluated. ?->only guards against null — it does not prevent errors from calling genuinely undefined methods on non-null objects.?->cannot be used as an assignment target; it is a read-only chaining operator.
Practice what you learned
1. What is the correct syntax for a named argument in a PHP function call?
2. Given `function f($a, $b = 1, $c = 2)`, which call correctly mixes positional and named arguments?
3. What does `$user?->profile?->address?->city` evaluate to if `$user->profile` is null?
4. Which statement about ?-> is FALSE?
5. If $obj is not null but $obj->realMethod() doesn't exist as a method, what happens when calling $obj?->realMethod()?
Was this page helpful?
You May Also Like
Functions in PHP
Learn how PHP functions are declared, typed, and invoked, including default parameters, variadics, references, and closures for reusable logic.
Type Declarations and Strict Types
PHP supports optional scalar and object type declarations on parameters, return values, and properties, with strict_types controlling how aggressively the engine coerces mismatched values.
Classes and Objects
Explore PHP's object-oriented foundations: declaring classes, constructing objects, typed properties, visibility, and constructor promotion.
Exceptions and Error Handling
Learn how PHP represents runtime failures as throwable objects, how try/catch/finally blocks control the flow around them, and how to design a clean exception hierarchy for your application.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics