必填参数$xxx在可选参数$yyy之后。

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

升级到PHP 8.0后,运行像这样的代码会抛出此错误:

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

这在过去的PHP版本中已经可以正常工作。


3
将参数的顺序更改,将必需的参数 $xxx 放在可选参数 $yyy 的前面。 - Darren Murphy
这个问题已经有了答案。按照你的建议去做意味着需要重写代码库中使用你的函数的每一个地方。 - miken32
为了快速解决问题,请使用function test_function(int $var1 = 2, int $var2=0),因为无论在何处使用该函数,都会传递一个值给$var2。然后在空闲时间内,搜索并更新您的代码。 - bluepinto
6个回答

60

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

新的废弃仅确保函数签名遵循常识假设:必须出现的必需参数应始终在可选参数之前声明。

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

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

5
"由于在调用函数时需要指定所有参数(直到最后一个必需的参数),我不同意 https://3v4l.org/Nb6i6 ;)" - Rain
3
非常出色的吹毛求疵! - miken32
7
“编写这样的函数从来没有意义” - 我不同意。有时为了可读性或简洁性,参数可能需要以不同的顺序排列。这种废弃似乎是一种不必要而烦人的改变。 - Enverex
3
在这种情况下指定的默认值永远不会被使用,因此它没有任何作用。我已经以职业 PHP 程序员身份工作超过 15 年了,从未需要这样做。参数顺序和默认值并不适用于文档编写,这就是 PHPDoc 的作用。 - miken32
7
@Rain - 我也不同意。我的两分意见是,这个PHP8废弃并没有经过深思熟虑。在PHP8中,他们添加了命名参数,这意味着你现在可以按任何顺序调用参数,只要你按名称调用它们就行,如下所示: func(param1: "value1", param2: "value2")因此,该语法支持在任何顺序上指定任何参数的默认值。@miken32 - 你说“因为(直到最后一个必需参数)在函数被调用时必须指定所有参数”- 这已经不再正确了。 - Ray Perea
显示剩余4条评论

11
必需的参数应该首先出现,且没有默认值。
function test_function(int $xxx, int $yyy = 2)
{
    return $xxx * $yyy;
}
 

然后在您的代码中更新该方法的每个使用? - miken32
我认为除非它抛出错误,否则您不需要这样做。 - Alemoh Rapheal Baja
2
必须首先提供没有默认值的参数。 - Alemoh Rapheal Baja

0

如果一个带有默认值的参数后面跟着一个必需参数,则默认值无效。

这在 PHP 8.0.0 中已被弃用,通常可以通过以下方法解决:

  1. 删除默认值
  2. 按照上述建议更改参数位置

而不会影响功能。

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

我遇到了以下错误:

ErrorException Required parameter $id follows optional parameter $getLink

以下代码生成了此异常

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

为解决此错误,我按照以下代码建议更改了参数的位置:
 public function fo($id, getLink = null)
    { ......
    }

完成了 =)


你每次使用该方法时都需要更改代码。为什么不在第二个参数上设置默认值,而要这样做呢? - miken32
@miken32 "如果默认值参数后面跟着一个必需参数,则默认值参数无效。"此功能在 PHP 8.0.0 中已被弃用,并且通常可以通过删除默认值或更改参数位置来解决,而不会影响功能。 - Omkar Ghurye
1
它完全改变了函数的功能;现在你必须找到并重写使用此函数的每一行代码。我的问题是,为什么这比放弃默认值更好,而放弃默认值不需要对其他代码进行任何更改?更不用说这种次优方法已经在另一个答案中给出了。 - miken32

0

如果有人试图找到需要更新的函数,您可以在Linux中使用此正则表达式通过grep输出结果到名为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

希望这能帮助那些试图查找和纠正错误的人。

相信ERE不支持懒惰匹配,所以所有的 *? 都是多余的。有些地方应该使用 +。但是,实际上,IDE将是最好的工具。它可以捕获像grep无法捕获的多行签名等内容。 - miken32
1
你可能也可以使用PHP内置的标记解析器来完成这个任务,但这不是一个简短的解决方案! - miken32
@miken32 - 在Linux下使用测试脚本进行了测试,并匹配了我能想到的所有组合。但还是建议您直接测试并确认,不要猜测。可能有不同的版本,我不确定。我只知道以上内容找到了我需要的,但如果需要更新它以使其100%完美,则非常乐意这样做!- 谢谢,我会检查令牌解析器。 - Watts Epherson
我并不是说这个方法行不通,只是a) .*? 在ERE中与 .* 完全相同,b) 你的正则表达式允许使用类似于 \$[a-zA-Z0-9_]* 的空/无效参数。另外:{1} 量词是多余的,而大小写不敏感的搜索意味着不必检查 a-z 和 A-Z 两者。 - miken32

-1
我在使用PHP 8.0以上的版本时遇到了这个问题。 在我的情况下,我成功地通过切换回PHP 7.4版本来解决了这个问题。

-1

对我有效的解决方案是交换参数的位置,确保没有任何一个参数在默认值设置为 null 的参数后面。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接