Skip to content

Null coalesce operator behaves inconsistent with null safe operator on the left-hand side #19427

@JojOatXGME

Description

@JojOatXGME

Description

I noticed an inconsistency and wasn't sure whether this is intended. The New Features page for PHP 7.0 describes the null coalesce operator exprA ?? exprB as a shorthand for isset(exprA) ? exprA : exprB. However, this doesn't match the behavior I observed.

The following code:

<?php
$unset?->width();
$unset?->width() ?? '';
$unset->width() ?? '';
//echo isset($unset?->width()); //-> fatal error
//echo isset($unset->width()); //-> fatal error

Resulted in this output:

PHP Warning:  Undefined variable $unset in C:\Users\jojo\Entwicklung\eichhof-tage\bug.php on line 2
PHP Warning:  Undefined variable $unset in C:\Users\jojo\Entwicklung\eichhof-tage\bug.php on line 4

Based on the documentation from PHP 7.0, I would instead either expect a fatal error (would limit the applicability of the operator a lot) or an additional warning at line 3.

The documentation at Comparison Operators left a lot of room for interpretation.

The expression (expr1) ?? (expr2) evaluates to expr2 if expr1 is null, and expr1 otherwise.
In particular, this operator does not emit a notice or warning if the left-hand side value does not exist, just like isset().

This could be interpreted to say that the operator should indeed suppress the warning in $unset?->width() ?? '';. After all, the access to $unset is part of the left-hand side. However, the documentation also includes the following example:

// Raises a warning that $name is undefined.
print 'Mr. ' . $name ?? 'Anonymous';

Here, the documentation explicitly states that we get a warning for accessing an undefined variable from within the left-hand side. Based on this example, $unset?->width() ?? ''; should also raise a warning.

Personal Preference

I personally find the current behavior rather useful. I think it can be a rather common pattern to try to access some method of a potentially undefined variable. Having the null coalesce operator available in these cases is convenient. However, I don't want to use it as long as I am not sure whether this behavior is stable. I think if the behavior is kept, it should be explicitly documented. This seems a rather special case specific to the null-safe operator. The current behavior doesn't follow from the current documentation.

Related

PHP Version

PHP 8.4.11 (cli) (built: Jul 29 2025 18:01:15) (ZTS Visual C++ 2022 x64)
Copyright (c) The PHP Group
Zend Engine v4.4.11, Copyright (c) Zend Technologies
    with Xdebug v3.4.5, Copyright (c) 2002-2025, by Derick Rethans

Operating System

Microsoft Windows [Version 10.0.19045.6093]

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions