4

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

原始代码:

function exception_error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
}

我只是更改最后一个参数并使其成为可选参数:

function exception_error_handler($errno, $errstr, $errfile, $errline, $errcontext=[]) {
}

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

4

1 回答 1

6

这里有一些关于什么是可选的以及为什么是混淆的。

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

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

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

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

这个参数一直是“可选的”,因为完全不在签名中列出它是安全的。所有版本的 PHP 都将接受像这样带有 4 个参数的回调:

function my_error_handler($errno, $errstr, $errfile, $errline) {
   // ...
}

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

  • 您正在编写只能在 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
}

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

于 2020-12-08T18:13:35.370 回答