100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
PHP

Named Arguments and the Nullsafe Operator

Named arguments let callers pass function parameters by name in any order, and the nullsafe operator short-circuits chained property/method access safely when any link is null.

Modern PHP FeaturesIntermediate8 min readJul 9, 2026
Analogies

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
<?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
<?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 error

Named 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: value syntax 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 to null the 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

Was this page helpful?

Topics covered

#PHP#PHPProgrammingStudyNotes#Programming#NamedArgumentsAndTheNullsafeOperator#Named#Arguments#Nullsafe#Operator#StudyNotes#SkillVeris