PHP函数可选参数

133

我编写了一个可以接受10个参数的PHP函数,但只有2个是必需的。有时候,我想定义第8个参数,但不想为每个参数键入空字符串直到我到达第8个参数。

我想到的一个方法是传递一个带有数组参数的抽象函数,然后将其传递给真实函数。

是否有更好的方法来设置函数,以便只能传递我想要的参数?


4
相关链接:https://dev59.com/bXI95IYBdhLWcg3w3yFU - Pekka
很奇怪。 PHP中的内置函数可以有可选参数。那么为什么我们不能构建像那样的函数呢? - Rodrigo
6
请注意,许多这些答案已经过时... PHP现在支持具有可变长度参数列表的函数 - ashleedawg
16个回答

72

在这种情况下,我所做的是传递一个数组,其中键是参数名称,而值是参数值。

$optional = array(
  "param" => $param1,
  "param2" => $param2
);

function func($required, $requiredTwo, $optional) {
  if(isset($optional["param2"])) {
    doWork();
  }
}

对于你的例子,$optional 不需要在函数内设置为全局变量吗? - user481826
1
全局变量?不需要。在调用函数之前,你可以创建该数组并将其传递给函数。我的代码是Matt Balls所描述的应该做的事情的一个例子。 - Rabbott
不仅仅是“使用数组”的建议,还有更多可以做的——看看Walf在类似问题中的答案以及同一线程中更详细的示例。 - DJDave

68
让该函数接收一个参数:数组。将实际参数作为数组中的值传入。
编辑:Pekka评论中的链接 已经总结了这个问题。

2
很奇怪。PHP中的内置函数可能具有可选参数。那么为什么我们不能构建这样的函数呢? - Rodrigo
2
@Rodrigo,像这样定义函数是完全可行的。但它们是位置可选的,对于超过一个可选参数的情况来说非常糟糕。 - Matt Ball
1
好的,我之前尝试使用[ ],现在我知道该如何在这里实现了:https://dev59.com/Q3VD5IYBdhLWcg3wRpaX#34869 - Rodrigo
不仅仅是“使用数组”的建议,还有更多可以做的 - 查看Walf在类似问题中的答案以及同一线程中更详细的示例。 - DJDave

57
要达成你想要的目的,使用一个数组就可以了,就像Rabbot所说的那样(尽管如果过度使用会变得繁琐且难以维护)。或者只需使用传统的可选参数即可。
//My function with tons of optional params
function my_func($req_a, $req_b, $opt_a = NULL, $opt_b = NULL, $opt_c = NULL)
{
  //Do stuff
}
my_func('Hi', 'World', null, null, 'Red');

然而,我通常会发现,当我开始编写一个具有那么多参数的函数/方法时,往往是代码异味,可以重构/抽象成更清晰的东西。

//Specialization of my_func - assuming my_func itself cannot be refactored
function my_color_func($reg_a, $reg_b, $opt = 'Red')
{
  return my_func($reg_a, $reg_b, null, null, $opt);
}
my_color_func('Hi', 'World');
my_color_func('Hello', 'Universe', 'Green');

在2010年,像“代码异味”、“重构”或“代码维护”这样的概念在我们的社区中并不流行。你比我们大多数人都要先进一步 :) - Billal Begueradj

23

您可以将默认值设置为null。

<?php
function functionName($value, $value2 = null) {
// do stuff
}

2
最佳答案,但请用日期类型的非位替换null。例如,对于数组,请使用array() - Mohamed hesham

17
在 PHP 5.6 及更高版本中,参数列表可以包含 ... 标记来表示该函数接受可变数量的参数。这些参数将作为数组传递给给定的变量;例如:
使用 ... 访问可变参数的示例
<?php
function sum(...$numbers) {
    $acc = 0;
    foreach ($numbers as $n) {
        $acc += $n;
    }
    return $acc;
}

echo sum(1, 2, 3, 4);
?>

以上示例将输出:

10

PHP文档中关于可变长度参数列表的说明


这个回答值得更多积分。虽然对于我的具体情况不适用,但信息很好,易于理解。PHP 7.3即将发布!5.6和7已经终止支持(EOL)。 - AdheneManx

16

PHP 8 开始,你可以使用命名参数

function namedParameters($paramOne, $paramTwo, $paramThree = 'test', $paramFour = null)
{
    dd($paramOne, $paramTwo, $paramThree, $paramFour);
}

我们现在可以使用 required 参数以及我们想要与函数中指定的默认值不同的 可选参数 来调用此函数。

namedParameters('one', 'two', paramFour: 'four');

结果:

// "one", "two", "test", "four"

1
这是最好的解决方案,尤其是当你处理现有的代码/函数时。将参数转换为数组对于在整个代码库中广泛使用的函数来说很难改变。 - Chiwda

13

注意:这是一个针对PHP 5.5及以下版本的旧答案。 PHP 5.6+ 支持默认参数。

在 PHP 5.5 及以下版本中,您可以使用以下两种方法之一来实现此目的:

  • 使用 func_num_args()func_get_arg() 函数;
  • 使用 NULL 参数;

如何使用

function method_1()
{
  $arg1 = (func_num_args() >= 1)? func_get_arg(0): "default_value_for_arg1";
  $arg2 = (func_num_args() >= 2)? func_get_arg(1): "default_value_for_arg2";
}

function method_2($arg1 = null, $arg2 = null)
{
  $arg1 = $arg1? $arg1: "default_value_for_arg1";
  $arg2 = $arg2? $arg2: "default_value_for_arg2";
}

我更喜欢第二种方法,因为它干净易懂,但有时可能需要用第一种方法。


1
你需要在这里使用双等号"==",否则所有的表达式都会返回true。此外,第二个例子中的表达式总是返回true,因为一个变量总是等于它本身。 - chuckieDub
好的观点,但实际上这个代码是有效的。在PHP中,这段代码$x = null; if ($x) echo "true"; else echo "false";将打印出"false",即使$x变量有一个值(在此代码中为"null")。另外,在两种方法中我们都使用了三元运算符,所以只使用一个"="是正确的。如果你用method(); method(1); method(1, 2);测试,那么第一次调用将把arg1和arg2与默认值关联起来,第二次调用将把第二个arg与默认值关联起来,并把"1"赋给第一个arg。最后一次调用将不关联默认值。 - Daniel Loureiro
1
function method_2($arg1 = "default_value_fot_arg1", $arg2 = "default_value_fot_arg2") { 所以PHP处理参数的事情,你也可以将null作为参数传递(为什么人们使用null我不知道) - nerkn
1
@nerkn,你说得对,PHP目前支持默认参数。哈哈,我记得我们需要做很多变通才能实现简单的事情。好时光: P尽管如此,您仍然可以在旧代码(5.5之前)中看到这些方法。 - Daniel Loureiro

4
我认为,您也可以将对象用作参数传输。
$myParam = new stdClass();
$myParam->optParam2 = 'something';
$myParam->optParam8 = 3;
theFunction($myParam);

function theFunction($fparam){      
  return "I got ".$fparam->optParam8." of ".$fparam->optParam2." received!";
}

当然,在这个函数中,您需要为“optParam8”和“optParam2”设置默认值,否则您将会遇到“注意:未定义属性:stdClass::$optParam2”的情况。
如果使用数组作为函数参数,在设置默认值方面,我喜欢使用以下方式:
function theFunction($fparam){
   $default = array(
      'opt1' => 'nothing',
      'opt2' => 1
   );
   if(is_array($fparam)){
      $fparam = array_merge($default, $fparam);
   }else{
      $fparam = $default;
   }
   //now, the default values are overwritten by these passed by $fparam
   return "I received ".$fparam['opt1']." and ".$fparam['opt2']."!";
}

2
自 PHP 7.1.0 起,可以在类型名称前加上问号(?)来标记类型声明可为空。这表示该值可以是指定的类型或 null。
<?php
    function name(?string $varname){
        echo is_null($varname);
    }
    name();
    name('hey');
?>

更多信息请参考:点击这里


该链接提供有关可空类型声明的更多信息。

2
function yourFunction($var1, $var2, $optional = Null){
   ... code
}

你可以创建一个普通函数,然后通过给可选变量设置默认的Null值来添加它们。
Null仍然是一个值,如果你没有为该变量调用函数并传入值,它也不会为空,因此不会出现错误。
"最初的回答"

2
能否进一步解释一下?给定的代码语法无效,因为变量名不能以数字开头。 - Nico Haase

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