带有可选参数的 PHP 函数
Posted
技术标签:
【中文标题】带有可选参数的 PHP 函数【英文标题】:PHP Function with Optional Parameters 【发布时间】:2011-04-28 02:15:46 【问题描述】:我写了一个 php 函数,它可以接受 10 个参数,但只需要 2 个。有时,我想定义第八个参数,但我不想在到达第八个之前为每个参数输入空字符串。
我的一个想法是传递一个带有参数数组的抽象函数,然后将其传递给真正的函数。
有没有更好的方法来设置函数,这样我就可以只传入我想要的参数?
【问题讨论】:
相关:***.com/questions/2112913 这很奇怪。 php 中的内置函数可能具有可选参数。那么为什么我们不能构建这样的函数呢? 请注意,其中许多答案已过时... PHP 现在支持 functions with variable-length argument lists。 【参考方案1】:我在这种情况下所做的是传递一个数组,其中键是参数名称,值是值。
$optional = array(
"param" => $param1,
"param2" => $param2
);
function func($required, $requiredTwo, $optional)
if(isset($optional["param2"]))
doWork();
【讨论】:
对于你的例子,$optional 不需要在函数中设置为全局的吗? 全球?不..?在调用函数之前创建该数组,然后传递它。我的代码是 Matt Balls 描述应该做什么的示例。 除了“使用数组”的建议之外,还有更多的工作可以做——看看 Walf 对a similar question 的回答以及同一线程中更深入的示例【参考方案2】:让函数接受一个参数:一个数组。将实际参数作为数组中的值传入。
编辑:the link in Pekka's comment 只是总结了一下。
【讨论】:
这很奇怪。 php 中的内置函数可能具有可选参数。那么为什么我们不能构建这样的函数呢? @Rodrigo 定义这样的函数是绝对可行的。虽然它们是位置可选的,但对于单个可选参数之外的任何东西来说都是非常糟糕的。 好的,我正在尝试使用 [ ],现在我可以在这里看到如何操作了:***.com/a/34869/1086511 除了“使用数组”的建议之外,还有更多工作要做——看看 Walf 对a similar question 的回答以及同一个线程中更深入的示例【参考方案3】:要完成您想要的,请使用数组Like Rabbot said(尽管如果过度使用这可能会成为记录/维护的痛苦)。或者只使用传统的可选参数。
//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 年,“代码异味”、“重构”或“代码维护”等概念在我们的社区中并不流行。你比我们大多数人先一步:)【参考方案4】:您可以将默认值设置为 null。
<?php
function functionName($value, $value2 = null)
// do stuff
【讨论】:
最佳答案,但请将null
替换为日期类型的非位。例如 array()
用于数组【参考方案5】:
在 PHP 5.6 及更高版本中,参数列表可能包含 ... 标记,以表示函数接受可变数量的参数。参数将作为数组传递给给定的变量;例如:
使用 ... 访问变量参数的示例
<?php
function sum(...$numbers)
$acc = 0;
foreach ($numbers as $n)
$acc += $n;
return $acc;
echo sum(1, 2, 3, 4);
?>
上面的例子会输出:
10
Variable-length argument lists PHP Documentation
【讨论】:
这个回复值得加分。不适合我的具体情况,但信息很好且易于理解。 PHP 7.3 即将推出! 5.6 和 7 已停产。【参考方案6】:注意:这是一个旧答案,适用于 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";
我更喜欢第二种方法,因为它简洁易懂,但有时您可能需要第一种方法。
【讨论】:
这里需要双“=”,否则所有表达式都将返回 true。此外,第二个示例中的表达式将始终返回 true,因为变量始终等于自身。 好点,但这确实有效。在 PHP 中,此代码$x = null; if ($x) echo "true"; else echo "false";
将打印“false”,即使 $x var 具有值(此代码中为“null”)。此外,在这两种方法中,我们都使用三元运算符,因此只使用一个“=”是正确的。如果您使用method(); method(1); method(1, 2);
进行测试,那么第一次调用会将 arg1 和 arg2 与默认值相关联,第二次调用会将第二个 arg 与默认值相关联,并且第一个 arg 为“1”。最后一次调用不会关联默认值。
function method_2($arg1 = "default_value_fot_arg1", $arg2 = "default_value_fot_arg2") 所以php处理参数的东西,你也可以传递null作为参数(为什么人们使用null我不知道)
@nerkn,你说得对,PHP 目前支持默认参数。大声笑,我记得当我们需要做很多变通方法来实现简单的事情时。好时光:P 不过,您仍然可以在旧代码(5.5 之前)中看到这些方法。【参考方案7】:
从PHP 8
开始你可以使用named arguments:
function namedParameters($paramOne, $paramTwo, $paramThree = 'test', $paramFour = null)
dd($paramOne, $paramTwo, $paramThree, $paramFour);
我们现在可以使用required
参数和仅可选参数调用此函数,我们希望与我们在函数中指定的default
值不同。
namedParameters('one', 'two', paramFour: 'four');
结果:
// "one", "two", "test", "four"
【讨论】:
【参考方案8】:我认为,您也可以将对象用作参数传输。
$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”设置默认值,否则你会得到“Notice: Undefined property: 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']."!";
【讨论】:
【参考方案9】:如果创建具有有效状态的对象只需要两个值,您可以简单地删除所有其他可选参数并为它们提供设置器(除非您不希望它们在运行时更改)。然后只需使用两个必需的参数实例化对象,并根据需要通过 setter 设置其他参数。
进一步阅读
Martin Fowler on Constructor vs Setter Injection 和 Dependency injection through constructors or property setters?【讨论】:
【参考方案10】:我知道这是一篇旧帖子,但我遇到了像 OP 这样的问题,这就是我想出的。
您可以传递的数组示例。如果需要特定订单,您可以重新订购,但对于这个问题,这将按照要求进行。
$argument_set = array (8 => 'lots', 5 => 'of', 1 => 'data', 2 => 'here');
这是可管理的,易于阅读,并且可以在编码中的任何地方立即添加和删除数据提取点,并且仍然避免大规模重写。我使用整数键来计算 OP 原始问题,但字符串键也可以很容易地使用。事实上,为了可读性,我会建议它。
为方便起见,将其粘贴到外部文件中
function unknown_number_arguments($argument_set)
foreach ($argument_set as $key => $value)
# create a switch with all the cases you need. as you loop the array
# keys only your submitted $keys values will be found with the switch.
switch ($key)
case 1:
# do stuff with $value
break;
case 2:
# do stuff with $value;
break;
case 3:
# key 3 omitted, this wont execute
break;
case 5:
# do stuff with $value;
break;
case 8:
# do stuff with $value;
break;
default:
# no match from the array, do error logging?
break;
return;
如果是文件,请将其放在开头。
$argument_set = array();
只需使用这些来根据数据的来源分配下一条数据使用编号/命名。
$argument_set[1][] = $some_variable;
最后传递数组
unknown_number_arguments($argument_set);
【讨论】:
【参考方案11】:function yourFunction($var1, $var2, $optional = Null)
... code
您可以创建一个常规函数,然后通过给它们一个默认的 Null 值来添加您的可选变量。
Null 仍然是一个值,如果您不使用该变量的值调用函数,它就不会为空,因此不会出错。
【讨论】:
你能进一步解释一下吗?给定的代码在语法上无效,因为变量名不能以数字开头【参考方案12】:如果您通常只传入第 8 个值,则可以重新排序参数,使其位于第一个。您只需要指定参数,直到您要设置的最后一个参数。
如果您使用不同的值,则有 2 个选项。
一种方法是创建一组封装函数,它们采用不同的参数并在其他函数上设置默认值。如果您只使用几个组合,这很有用,但很快就会变得非常混乱。
另一个选项是传递一个数组,其中键是参数的名称。然后,您可以使用键检查数组中是否存在值,如果没有则使用默认值。但同样,如果您有很多参数,这可能会变得混乱并添加大量额外代码。
【讨论】:
【参考方案13】:PHP 允许使用默认参数 (link)。在您的情况下,您可以将 3 到 8 的所有参数定义为 NULL 或空字符串“”,具体取决于您的功能代码。这样就可以只用前两个参数调用函数了。
例如:
<?php
function yourFunction($arg1, $arg2, $arg3=NULL, $arg4=NULL, $arg5=NULL, $arg6=NULL, $arg7=NULL, $arg8=NULL)
echo $arg1;
echo $arg2;
if(isset($arg3))echo $arg3;
# other similar statements for $arg4, ...., $arg5
if(isset($arg8))echo $arg8;
【讨论】:
有趣的想法...但是您的建议并没有解决问题。实际上,如果您添加有关正在回显的参数的信息(例如,通过使用echo " this is arg3: " . $arg3;
等,您将看到调用例如yourFunction(3, 2, $arg8=5);
将打印32 this is arg3: 5
。问题是参数位置在传递时仍然很重要PHP中的可选参数...参数名称不足以将参数值映射到参数名称。【参考方案14】:
只需设置Null忽略不想使用的参数,然后根据位置设置需要的参数即可。
function myFunc($p1,$p2,$p3=Null,$p4=Null,$p5=Null,$p6=Null,$p7=Null,$p8=Null)
for ($i=1; $i<9; $i++)
$varName = "p$i";
if (isset($$varName))
echo $varName." = ".$$varName."<br>\n";
myFunc( "1", "2", Null, Null, Null, Null, Null, "eight" );
【讨论】:
【参考方案15】:func( "1", "2", default, default, default, default, default, "eight" );
【讨论】:
这不是有效的 PHP。default
是 keyword in PHP。以上是关于带有可选参数的 PHP 函数的主要内容,如果未能解决你的问题,请参考以下文章