可选参数$yyy后面$xxx必需参数

Required parameter $xxx follows optional parameter $yyy

提问人:miken32 提问时间:12/15/2020 最后编辑:miken32 更新时间:11/1/2023 访问量:79151

问:

Deprecated: Required parameter $xxx follows optional parameter $yyy in...

自从升级到 PHP 8.0 以来,在运行如下代码时会抛出此错误:

function test_function(int $var1 = 2, int $var2) {
    return $var1 / $var2;
}

这在以前的PHP版本中一直有效,没有问题。

函数签名 php-8

评论

3赞 Darren Murphy 4/27/2021
更改参数的顺序,将$xxx放在可选参数$yyy之前。
0赞 miken32 4/27/2021
这个问题已经有了答案。按照你的建议去做,意味着在你的代码库中重写你的函数的每一次使用。
0赞 bluepinto 6/22/2023
为了快速解决,请使用 ,因为无论在何处使用该函数,它都会为 传递一个值。然后在业余时间搜索并更新您的代码。function test_function(int $var1 = 2, int $var2=0)$var2

答:

60赞 3 revsmiken32 #1

这种函数声明方式在 PHP 8.0 中已被弃用。编写这样的函数从来就没有意义,因为在调用函数时需要指定所有参数(直到最后一个必需的参数)。它还导致使用 ReflectionFunctionAbstract来分析函数和方法的混淆

新的弃用只是确保函数签名遵循常识性假设,即必须出现的必需参数应始终在可选参数之前声明。

应重写该函数以删除前面参数的默认值。由于在不声明所有参数的情况下永远无法调用该函数,因此这应该不会影响其功能。

function test_function(int $var1, int $var2) {
    return $var1 / $var2;
}

评论

5赞 Rain 12/15/2020
“因为在调用函数时需要指定所有参数(直到最后一个必需的参数)” 。我不同意 3v4l.org/Nb6i6 ;)
3赞 miken32 12/15/2020
非常令人印象深刻的吹毛求疵!👍🏼
7赞 Enverex 4/8/2021
“像这样编写函数从来就没有意义”——我不同意。通常情况下,出于理智或可读性的原因,参数的顺序可能会有所不同。这种弃用似乎是一个不必要且令人讨厌的更改。
3赞 miken32 4/9/2021
@Enverex在这种情况下指定的默认值永远无法使用,因此它没有任何用处。我从事PHP专业编程已经超过15年了,我从来没有做过。参数顺序和默认值不打算用作文档,这就是 PHPDoc 的用途。
7赞 Ray Perea 7/19/2021
@Rain - 我也不同意。我的 2 美分......这个 PHP8 弃用根本没有经过深思熟虑。在 PHP8 中,他们添加了命名参数,这意味着您现在可以按任何顺序调用参数,只要您按如下名称调用它们: 因此,该语法补充了能够以任何顺序为任何参数指定默认值。@miken32 - 你说“因为在调用函数时需要指定所有参数(直到最后一个必需的参数)” - 这不再是真的了func(param1: "value1", param2: "value2")
11赞 Alemoh Rapheal Baja 4/15/2021 #2

没有默认值的必需参数应排在最前面。

function test_function(int $xxx, int $yyy = 2)
{
    return $xxx * $yyy;
}
 

评论

0赞 miken32 4/16/2021
然后在整个代码中更新该方法的每次用法?
0赞 Alemoh Rapheal Baja 4/16/2021
我认为您不必这样做,除非它会抛出错误。
2赞 Alemoh Rapheal Baja 6/17/2021
没有默认值的必需参数应排在最前面
0赞 Omkar Ghurye 2/20/2022 #3

“如果具有默认值的参数后跟必需的参数,则默认值不起作用。”

从 PHP 8.0.0 开始,这已被弃用,通常可以解决

  1. 通过删除默认值
  2. 通过如上所述更改参数的位置

,而不更改功能。

这种方法在我的情况下有效=)

我面临以下错误:

ErrorException 必需参数$id遵循可选参数$getLink

以下代码生成了此异常

public function fo($getLink = null , $id)
{ ......
}

为了解决这个错误,我按照以下代码中的建议更改了参数的位置:

 public function fo($id, getLink = null)
    { ......
    }

完成 =)

评论

0赞 miken32 2/21/2022
每次使用该方法的地方都需要更改代码。为什么要这样做,而不是只在第二个参数上设置默认值?
0赞 Omkar Ghurye 2/23/2022
@miken32 “如果具有默认值的参数后跟必需参数,则默认值无效。从 PHP 8.0.0 开始,这已被弃用,通常可以通过删除默认值或更改上述建议的参数位置来解决,而无需更改功能。
1赞 miken32 2/23/2022
它完全改变了功能;现在,您必须查找并重写使用此函数的每一行代码。我的问题是,为什么这比只删除默认值更好,因为默认值不涉及对其他代码的更改?更不用说这种低于标准的方法已经在另一个答案中给出了。
-1赞 AYOMIDE ADEBAYO 6/9/2022 #4

对我来说效果很好的解决方案是交换参数的位置,确保默认值设置为 null 的任何参数之后都没有参数。

0赞 Watts Epherson 3/16/2023 #5

如果有人试图找到一种方法来发现需要更新的函数,您可以通过 grep 在 linux 中使用此正则表达式,它将结果输出到名为 results.txt 的文件。它只会在 .php 文件中搜索。

我花了一段时间才让它工作,它可能需要更多的调整!

flag -i = Case insensitive search
flag -n = print line number match was found on with the file found
flag -r = recursive from current location downwards
flag -E = Use extended regular expression rules


grep -irnE --include \*.php 'function ([a-zA-Z0-9_]*?)[ ]?\(.*?\$[a-zA-Z0-9_]*?=.*?(\$[a-zA-Z0-9_]*?)[\),]{1}[^\{]*?' > results.txt

希望这对任何试图查找和纠正错误的人有所帮助。

评论

0赞 miken32 3/16/2023
可以肯定的是,ERE不支持惰性匹配,因此所有这些都是多余的。在一些地方,它应该是一个。但实际上,IDE将是最好的工具。它将捕获 grep 无法捕获的多行签名之类的东西。*?+
1赞 miken32 3/16/2023
你也可以使用 PHP 的内置令牌解析器来做到这一点,尽管这不是一个简短的解决方案!
0赞 Watts Epherson 3/16/2023
@miken32 - 使用测试脚本在 linux 中对其进行了测试,并将我能想到的所有内容作为组合进行匹配。请自己直接测试并确认,因为不建议猜测。可能有不同的口味,不知道。我只知道上面也找到了我需要的东西,但如果需要,非常乐意更新它,所以 100% 完美!- 将检查令牌解析器,谢谢。
0赞 miken32 3/17/2023
我并不是说它不起作用,只是 a) 与 ERE 中的完全相同,并且 b) 您的正则表达式允许使用空/无效参数,例如 .另外:量词是多余的,不区分大小写的搜索意味着不必同时检查 a-z 和 A-Z。.*?.*\$[a-zA-Z0-9_]*{1}
-1赞 Omkar Ghurye 11/1/2023 #6

我在 8.0 以上的 PHP 版本中遇到了这个问题。 在我的情况下,我设法通过转换回 PHP 版本 7.4 来解决这个问题。