PHP 8.4: exit/die 从语言构造修改为函数
exit
关键词及其别名 die
是输出消息并终止当前脚本的语言构造。在 CLI 应用中,exit
/die
可用于通过给定退出码终止应用。
有些语言构造,如 require
、include
、echo
及 exit
,与 PHP 函数类似,但它们有自己的标记和功能,不一定有返回值,也不需要用括号调用。
由于 exit
和 die
是语言构造,它允许以各种方式调用它。它不需要括号,并接受一个字符串或 int 值,这些值要么打印到 STDOUT
(如果是字符串),要么用作退出码(如果是 int
):
exit; // Allowed
exit(); // Allowed
exit(1); // Allowed
exit("Fatal error, exiting"); // Allowed
在 PHP 8.4 之前,它的可选参数接收一个 string
或一个 int
值,不过并不遵循同样的强制类型转换或者严格类型行为。
declare(strict_types=1);
exit([]);
Warning: Array to string conversion in ... on line ...
Array
在 PHP 8.4 中,exit
和 die
被声明为 PHP 函数。它们具有特殊的处理方式,允许在没有括号的情况下调用它们,以确保与旧 PHP 应用的向后兼容性。
exit
和 die
函数摘要
function exit(string|int $status = 0): never {}
function die(string|int $status = 0): never {}
函数 die
等价于 exit
函数。这两个函数都在全局命名空间中进行声明,返回类型都为 never
。
未修改:不带括号调用 exit
和 die
为确保向后兼容性,exit
和 die
函数仍然可用不使用括号进行调用。这样的调用不会发出任何弃用通知。T
exit; // Allowed
die; // Allowed
未修改:exit
和 die
不能使用 disable_functions
INI 指令禁用
新增的 exit
和 die
函数不能使用 disable_functions
INI 指令禁用。这么做会发出一个 PHP 警告,且该函数保持启用:
[PHP]
disable_functions=exit,die
Warning: Cannot disable function exit()
Warning: Cannot disable function die()
未修改:exit
和 die
不可用于函数名、类名、常量名和 goto
标签
exit
和 die
不允许是函数名或常量名,即使在命名空间内也是如此。此外,exit
和 die
不能用作 goto
的标签。
以下所有代码在所有 PHP 版本(包括 PHP 8.4 及更高版本)中都会导致语法错误。
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
仍然可以使用 define
来声明具有 exit
和 die
名称的常量。但是,请注意,尝试使用常量将调用 die
或 exit
,而不是检索常量值。
exit:
echo "Called";
Parse error: syntax error, unexpected token ":"
未修改:exit
和 die
可用作枚举成员、类常量、方法和属性
exit
和 die
可用作类常量名、方法名和属性名。以下代码在所有 PHP 版本,包括 PHP 8.4 及更高版本,都是有效的。此外,因为枚举内部继承了 PHP 类结构 exit
和 die
也可以作为有效的枚举成员名使用:
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
类型处理变更
因为 exit
和 die
在 PHP 8.4 及更高版本中是 PHP 函数,所以它们现在遵循其他 PHP 函数遵循的标准类型处理。
ArgumentCountError
on additional parameters
之前,传递超过一个参数给 exit
/die
会导致语法错误。在 PHP 8.4 上,则会抛出 ArgumentCountError
异常。
exit(255, "foobar");
ArgumentCountError: exit() expects at most 1 argument, 2 given
非 strict_types
时的标准类型转换
与其他 PHP 函数的工作方式类似,exit
和 die
现在也遵循相同的类型转换/强制规则。这会影响向后兼容性,但可以说是朝着更正确的方向发展。
请注意:
- 在 PHP 8.4 之前,
exit(true)
被强制转换为exit("1")
,因此 “1” 被打印到STDOUT
,退出码为0
(无错误)。在 PHP 8.4 及更高版本中,这现在被解析为exit(1)
,退出码为1
(错误)。 - 传入
float
值将触发将浮点型转换为int
的隐式转换,会触发精度弃用消息。 - 传入
null
将触发弃用通知因为exit
/die
只接收string|int
。
strict_types
生效时将抛出 TypeError
异常
strict_types
生效时,传入不是 string
或 int
将抛出 TypeError
异常:
declare(strict_types=1);
exit(null);
TypeError: exit(): Argument #1 ($status) must be of type string|int, null given
exit
和 die
可被调用(callable)
因为 exit
和 die
是 PHP 函数,它们现在可以被用作标准的 PHP callable。
在 PHP 8.3 及之前的版本中,以下代码会失败,因为 exit
在这些版本中未被声明为 callable 函数。
$callable = 'exit';
$status = "My success message";
$callable($status);
$callable = exit(...);
$status = "My success message";
$callable($status);
上例使用了 first-class callable 语法。
向后兼容性影响
exit
和 die
现在是 PHP 函数。然而,这一变化在很大程度上与旧的 PHP 版本向后兼容,因为 exit
和 die
仍然不允许作为类、常量和函数名,并且继续允许作为类常量、属性和方法名。
只有 PHP 8.4 及更高版本支持使用 exit
和 die
作为可调用对象。
由于 exit
和 die
是旧 PHP 版本中的语言构造,因此不可能(也不需要)对这些函数进行 polyfill。