PHP 8.1 Never Return Type Explained

PHP 8.1 introduced the never return type, a feature designed to indicate that a function will never return a value to the caller. This article explains how the never return type behaves, its technical requirements, and how it differs from the existing void return type in PHP development.

What is the never Return Type?

The never return type is a “bottom type” in type theory. When you declare a function with a never return type, you are indicating to the PHP engine, static analyzers, and IDEs that this function will never complete its execution normally.

For a function to satisfy the never return type, it must perform one of the following actions: * Throw an exception (throw new Exception()). * Terminate script execution explicitly (using exit() or die()). * Enter an infinite loop (such as while (true) {}).

If a function declared with never attempts to return a value, or even exits naturally without throwing or terminating, PHP will trigger a TypeError.

Syntax and Behavior

Here is a practical example of a redirect function utilizing the never return type:

function redirectToDashboard(): never {
    header('Location: /dashboard');
    exit;
}

Because exit is called, the function never returns control to the line of code that called it, making never the correct type declaration.

If you attempt to write a function like this:

function invalidNever(): never {
    // This will cause a TypeError because the function finishes naturally
}

PHP will throw a compile-time error: Fatal error: A never-returning function must not return.

Difference Between never and void

While never and void may seem similar, they have distinct behaviors:

Inheritance Rules (Covariance and Contravariance)

In object-oriented PHP, the never type is considered a subtype of every other type (including void). This means: * A child class method can narrow a return type from void (or any other type) to never. * A child class method cannot widen a return type from never to void or any other type.

class ParentClass {
    public function terminate(): void {}
}

class ChildClass extends ParentClass {
    // This is valid because never is a subtype of void
    public function terminate(): never {
        exit;
    }
}

By using the never return type, developers can write safer, more expressive code that allows static analysis tools to better understand the control flow of an application.