PHP now has support for undefined!?

Before you dismiss this post as some cheap clickbait, please take a look at the following code and tell me if this is PHP:

<?php

function greeting(string $name, string|null|undefined $title = undefined) {
    $greeting = 'Hello';
    $greeting .= match ($title) {
        null => ' ',
        undefined => ' ??? ',
        default => " $title ",
    };
    $greeting .= $name;
    return $greeting;
}

echo greeting('John Doe');

Drumroll… it actually is perfectly valid PHP code.

I know what you are thinking: “This is not JavaScript. PHP does not have undefined.” And you would be correct. This is where I need to qualify my previous statement. The above code may be valid PHP but it does not execute successfully. Turns out, PHP really does not know about undefined.

Fatal error: Uncaught Error: Undefined constant “undefined”

The PHP runtime

But no worries, we can fix this minor problem with only two lines of code.

<?php

enum undefined { case undefined; }
define('undefined', undefined::undefined);

How it works

To make the function greeting() work, we need two things:

a) First, we need to have a type called undefined for the type annotation of the function parameter. An enum will do. A single enum case is required, otherwise we would not be able to do anything with it. The name of the case is irrelevant.

b) Second, we need a constant called undefined for the default argument value. The syntax function ($x = undefined) may look unfamiliar, but all it says is that the default value for $x is equal to the constant named ‘undefined’. The built-in function define() lets us create a global constant with that name.

What’s missing?

We have no language support for undefined whatsoever. Meaning, neither the null-safe nor null-coalescing operators work like they do in JavaScript:

<?php

enum undefined {
    case undefined;
    public function foo() {
        return 'Foo';   
    }
}
define('undefined', undefined::undefined);

var_dump(undefined ?? 'Fallback'); // Prints enum(undefined::undefined)

$obj = undefined;
var_dump($obj?->foo()); // Prints string(3) "Foo"

Wrapping up

Should you introduce this pseudo language extension into your production code base? Definitely not. In the end it is just minor syntactic sugar for referencing an enum case.

While I do think that singleton symbol-like objects may sometimes come in handy (see example), it is better to be explicit about it.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.