PHP 8.4: exit
/die
changed from language constructs to functions
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:
- Prior to PHP 8.4,
exit(true)
was coerced toexit("1")
, which resulted in "1" to be printed toSTDOUT
with exit code0
(no error). In PHP 8.4 and later, this is now interpreted asexit(1)
, causing the exit code to be1
(error). - Passing
float
values triggers Implicit conversion from float ... to int loses precision deprecation message. - Passing
null
triggers a deprecation becauseexit
/die
only acceptstring|int
.
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.