PHP 8.4: exit/die changed from language constructs to functions

Version8.4
TypeChange

The exit keyword and its alias die are language constructs that output a message and terminate the current script. In CLI applications, exit/die can be used to terminate the application with a given exit code.

Some language constructs such as require, include, echo, and exit work similarly to PHP functions, but they have their own tokens, functionality, and do not necessarily have return values nor need to be called with parentheses.

Due to exit and die being language constructs, it allowed various ways of calling it. It did not require parentheses, and accepted a string or an int value that were either printed to STDOUT (in case of string), or used as the exit code (in case of int):

exit; // Allowed
exit(); // Allowed
exit(1); // Allowed
exit("Fatal error, exiting"); // Allowed

The optional "parameter", prior to PHP 8.4, accepted a string or an int value, but it did not follow the same type juggling or strict typing behavior.

declare(strict_types=1);

exit([]);
Warning: Array to string conversion in ... on line ...
Array

In PHP 8.4, exit and die are declared as PHP functions. They have special handling to allow them to be called without the parentheses to ensure backward compatibility with older PHP applications.

exit and die function synopsis

function exit(string|int $status = 0): never {}

function die(string|int $status = 0): never {}

The function die is equivalent to the exit function. Both functions are declared in the global namespace. They both have return type never.

Unchanged: Calling exit and die without parentheses

To ensure backward compatibility, exit and die functions can still be called without parentheses. Calling them so does not emit any deprecation notices.

exit; // Allowed
die; // Allowed

Unchanged: exit and die cannot be disabled with disable_functions INI directives

The new exit and die functions cannot be disabled using the disable_functions directive. Doing so emits a PHP warning, and the functions remain enabled:

[PHP]
disable_functions=exit,die
Warning: Cannot disable function exit()
Warning: Cannot disable function die()

Unchanged: exit and die are not available for function names, class names, const names, and goto labels

exit and die are not allowed to be function or constant names, even inside a namespace. Further, exit and die are not available to be used as labels for goto.

All of the following snippets cause a syntax error in all PHP versions including PHP 8.4 and later.

function exit() {}

namespace Test;
function exit() {}
Parse error: syntax error, unexpected token "exit", expecting "("

const die = 42;
const EXIT = 42;
Parse error: syntax error, unexpected token "exit", expecting identifier

It is still possible to use define to declare a constant with exit and die names. However, note that attempting to use the constant will call the die or exit rather than retrieving the constant value.


exit:
echo "Called";
Parse error: syntax error, unexpected token ":"

Unchanged: exit and die can be used as Enum members, class constants, methods, and properties

exit and die can be used as class constant names, class method names, and property names. The following snippet is valid in all PHP versions including PHP 8.4 and later. Further, because Enums extend the PHP class structures internally, exit and die are valid Enum member names too:

class Test {
    public int $exit = 442;
    public int $die = 116;

    public const int exit = 42;
    public const int die = 16;

    public function exit() {
        return self::exit;
    }

    public function die() {
        return self::die;
    }
}

$c = new Test();
echo $c->exit(); // 42
echo $c->die(); // 16
echo $c->exit; // 442
echo $c->die; // 116
echo Test::exit; // 42
echo Test::die; // 16

Type Handling Changes

Because exit and die are PHP functions in PHP 8.4 and later, they now follow standard type handling the other PHP functions follow.

ArgumentCountError on additional parameters

Previously, passing more than one parameter to exit/die caused a syntax error. On PHP 8.4, this causes an ArgumentCountError exception.

exit(255, "foobar");
ArgumentCountError: exit() expects at most 1 argument, 2 given

Standard type-juggling when not on strict_types

Similar to how the rest of the PHP functions work, exit and die now also follow the same type-juggling/coercion rules. This impacts backward compatibility, but arguably in the more correct direction.

Notably:

TypeError exceptions when strict_types in effect

When strict_types=1 is in effect, passing any value other than string or int causes a TypeError exception:

declare(strict_types=1);

exit(null);
TypeError: exit(): Argument #1 ($status) must be of type string|int, null given

exit and die can be callables

Because exit and die are PHP functions, they can now be used as standard PHP callables.

In PHP 8.3 and older versions, the following snippets fail because exit is not declared as a callable function in those versions.

$callable = 'exit';
$status = "My success message";
$callable($status);
$callable = exit(...);
$status = "My success message";
$callable($status);

This example uses first-class callable syntax.

Backward Compatibility Impact

exit and die are now PHP functions. However, this change is largely backward compatible with older PHP versions because exit and die continue to be not allowed as class, constant, and function names, and continue to be allowed as class constant, property, and method names.

Using exit and die as callables is only supported on PHP 8.4 and later.

Due to exit and die being language constructs in older PHP versions, it's not possible (nor need to) polyfill these functions.


exit die RFC Discussion Implementation