Support the ongoing development of Laravel.io →
Article Hero Image

The "never" Type in PHP

1 Jul, 2025 5 min read

Photo by Joshua Hoehne on Unsplash

Introduction

There may be times when you're writing a function in PHP that you know will never return a value. This could be because the function always throws an exception, or maybe calls exit or die. In these cases, you might want to use the never type.

Admittedly, the never type isn't something I reach for very often, but it's useful in certain scenarios, especially when you want to make it clear to other developers that a function will not return normally.

In this article, we're going to explore the never type in PHP, how to use it, and some practical examples. I'll also include a cheat sheet at the end of this article that you can refer back to.

How to Use "never" in PHP

The never type was introduced in PHP 8.1 (released: November 2021) and is used to indicate that a function will never return. This signals to PHP, and other developers reading the code, that the function is not expected to return a value under any circumstances. This could be due to the function throwing an exception, or maybe calling something like exit or die.

The never type can only be used as a return type, and cannot be used as a parameter type.

Let's take a look at a quick example of how to use the never type in PHP:

public function doSomething(): never
{
    throw new Exception('Exception message here.');
}

As we can see in the example above, the doSomething function uses the never return type because it will always throw an exception.

Let's change our example and update the doSomething function to return a value instead of throwing an exception. We're doing this to purposely break the code and show how PHP handles it:

public function doSomething(): never
{
    return 'This will cause an error';
}

In our code example above, we are trying to return a string while using the never return type. This will result in a fatal error being thrown by PHP with the following message:

Fatal error: A never-returning function must not return in /in/32Ts2 on line 3

Implicit Returns with "never"

If a function is declared with a never return type, isn't able to implicitly return a value. Doing so will also result in a fatal error.

For example, let's imagine we have a method that is used to publish a blog post:

namespace App\Services;

use App\Enums\ArticleStatus;
use App\Models\Article;

class ArticleService
{
    public function publishArticle(Article $article): never
    {
        $article->published_at = now();
        $article->status = ArticleStatus::Published;

        $article->save();
    }
}

As we can see in the example above, the publishArticle method doesn't exit from the function or throw an exception. It also doesn't explicitly return a value. As a result, this means it will implicitly return and PHP will throw a fatal error when we try to call this method:

Fatal error: Uncaught TypeError: ArticleService::publishArticle(): never-returning function must not implicitly return

Using "never" with Intersection Types

The never type cannot be used in PHP as part of an intersection type.

For example, let's take the following code snippet:

public function doSomething(): never&string
{
    throw new Exception('This will cause an error');
}

Running this would result in a fatal error with the following message:

Fatal error: Type never cannot be part of an intersection type

Using "never" with Union Types

The never type cannot be used in PHP as part of a union type.

For example, let's take the following code snippet:

public function doSomething(): never|string
{
    throw new Exception('This will cause an error');
}

Running this would result in a fatal error with the following message:

Fatal error: never can only be used as a standalone type

Example Use Case

Now that we've covered the basics of the never type, let's take a look at a practical example of how it can be used in a real-world scenario.

If you've used Laravel or Symfony before, you'll likely be familiar with the dd (dump and die) function. This function is used to dump variables and stop the script execution. It can be quite a handy tool for debugging to quickly inspect variables and see their contents.

This functionality is made available via the symfony/var-dumper package. Let's take a look at how the never type is used in the dd function (https://github.com/symfony/var-dumper/blob/7.3/Resources/functions/dump.php):

if (!function_exists('dd')) {
    function dd(mixed ...$vars): never
    {
        if (!in_array(\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true) && !headers_sent()) {
            header('HTTP/1.1 500 Internal Server Error');
        }

        if (!$vars) {
            VarDumper::dump(new ScalarStub('🐛'));

            exit(1);
        }

        if (array_key_exists(0, $vars) && 1 === count($vars)) {
            VarDumper::dump($vars[0]);
        } else {
            foreach ($vars as $k => $v) {
                VarDumper::dump($v, is_int($k) ? 1 + $k : $k);
            }
        }

        exit(1);
    }
}

Now, we don't need to fully understand the entire implementation of the dd function, but we can see that there are only two places where the function will finish running. Both of these places use exit(1), which means the script will terminate at that point. This is a perfect example of a function that will never return a value, and thus it is declared with the never return type.

Cheat Sheet

The never type in PHP:

  • Is used to indicate that a function will never return.
  • Can only be used as a return type.
  • Cannot be used as a parameter type.
  • Cannot be used in intersection types.
  • Cannot be used in union types.
  • Is available since PHP 8.1.

Conclusion

In this article, we've explored the never type in PHP, how to use it, and a practical example of how it's used in the symfony/var-dumper package's dd function. Hopefully, you should now feel confident using the never type in your own PHP code.

If you enjoyed reading this post, you might be interested in checking out my 220+ page ebook "Battle Ready Laravel" which covers similar topics in more depth.

Or, you might want to check out my other 440+ page ebook "Consuming APIs in Laravel" which teaches you how to use Laravel to consume APIs from other services.

If you're interested in getting updated each time I publish a new post, feel free to sign up for my newsletter.

Keep on building awesome stuff! 🚀

Last updated 7 hours ago.
0
Like this article? Let the author know and give them a clap!
ash-jc-allen (Ash Allen) I'm a freelance Laravel web developer from Preston, UK. I maintain the Ash Allen Design blog and get to work on loads of cool and exciting projects 🚀

Other articles you might like

Article Hero Image June 30th 2025

Check if a Signed URL is Valid in Laravel Tests

Introduction There may be times when you want to check whether a URL in your Laravel application is...

Read article
Article Hero Image June 22nd 2025

Pass a Query Builder to "whereIn" to Reduce Your DB Queries

Introduction I recently learnt about a cool feature in Laravel that allows you to pass a query build...

Read article
Article Hero Image June 14th 2025

Asymmetric Property Visibility in PHP

Introduction Asymmetric visibility is a feature that was introduced in PHP 8.4 (released: November 2...

Read article

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2025 Laravel.io - All rights reserved.