函数 exception_error_handler() 的参数太少 - PHP8

Iba*_*nêz 6 php php-8

正如标题所说,这个错误发生在我身上。我搜索互联网并发现 https://github.com/processwire/processwire-issues/issues/1286#issuecomment-738880424

原始代码:

function exception_error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
}
Run Code Online (Sandbox Code Playgroud)

我只是更改最后一个参数并将其设为可选,如下所示:

function exception_error_handler($errno, $errstr, $errfile, $errline, $errcontext=[]) {
}
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么这个参数变成可选的?

IMS*_*SoP 12

关于什么是可选的以及为什么可选,这里存在一些混乱。

您定义的函数是一个回调,PHP 将使用某些参数来调用该回调,这些参数记录在该set_error_handler函数的手册页中。(请注意,在询问时,该页面使用了不同的措辞;在写完这个答案后,我提交了一个针对 PHP 8.0 更新它的补丁,并希望使其更加清晰)。

根据文档,旧版本的 PHP 将 5 个参数传递给回调,并接收第 5 个参数:

触发错误的范围内存在的每个变量的数组。

这会导致许多奇怪的行为并阻止引擎中的某些优化,因此在 PHP 7.2 中,鼓励删除此参数的使用。在 PHP 8.0 中,不再传递参数 - 也就是说,PHP 现在仅使用 4 个参数调用回调。

该参数始终是“可选的”,从某种意义上说,根本不将其列在签名中是安全的。像这样的带有 4 个参数的回调将被所有版本的 PHP 接受

function my_error_handler($errno, $errstr, $errfile, $errline) {
   // ...
}
Run Code Online (Sandbox Code Playgroud)

正确的解决方案是从函数中完全删除该参数,如果:

  • 您正在编写只能在 PHP 8.0 及更高版本上运行的代码;或者
  • 你实际上从未在函数中使用该参数

如果实现实际上依赖于该参数,则需要进行其他更改。您可能想包含带有默认值的参数(使其在不同意义上成为“可选”)并在旧版本的 PHP 上传递时使用它:

function my_error_handler($errno, $errstr, $errfile, $errline, $errcontext=[]) {
   // $errcontext will be populated on older PHP versions, 
   // but will always be an empty array on PHP 8.0 or above
   // Any functionality using it will become useless in future
}
Run Code Online (Sandbox Code Playgroud)

但是,您最好简单地删除依赖它的代码,并找到一个更面向未来的解决方案。