I am confused about default values for PHP functions. Say I have a function like this:
我对PHP函数的默认值感到困惑。假设我有一个这样的函数:
function foo($blah, $x = "some value", $y = "some other value") {
// code here!
}
What if I want to use the default argument for $x and set a different argument for $y?
如果我想用$x的默认参数为$y设置另一个参数呢?
I have been experimenting with different ways and I am just getting more confused. For example, I tried these two:
我一直在尝试不同的方法,我只是越来越困惑。例如,我尝试了这两种方法:
foo("blah", null, "test");
foo("blah", "", "test");
But both of those do not result in a proper default argument for $x. I have also tried to set it by variable name.
但这两种方法都不能得到正确的x的默认值。我也尝试用变量名来设置它。
foo("blah", $x, $y = "test");
I fully expected something like this to work. But it doesn't work as I expected at all. It seems like no matter what I do, I am going to have to end up typing in the default arguments anyway, every time I invoke the function. And I must be missing something obvious.
我完全预料到这样的事情会发生。但这根本不是我想的那样。无论我做什么,每次调用函数时,我都必须输入默认参数。我一定漏掉了一些明显的东西。
9 个解决方案
#1
119
I would propose changing the function declaration as follows so you can do what you want:
我建议将功能声明更改如下,以便您可以做您想做的:
function foo($blah, $x = null, $y = null) {
if (null === $x) {
$x = "some value";
}
if (null === $y) {
$y = "some other value";
}
code here!
}
This way, you can make a call like foo('blah', null, 'non-default y value');
and have it work as you want, where the second parameter $x
still gets its default value.
这样,您可以调用foo('blah', null, 'non-default y value');如果第二个参数$x仍然得到它的默认值,那么它就可以按照您的要求工作。
With this method, passing a null value means you want the default value for one parameter when you want to override the default value for a parameter that comes after it.
通过这个方法,传递一个空值意味着当您想要覆盖一个参数的默认值时,您需要一个参数的默认值。
As stated in other answers,
如其他答案所述,
default parameters only work as the last arguments to the function. If you want to declare the default values in the function definition, there is no way to omit one parameter and override one following it.
默认参数仅作为函数的最后一个参数。如果希望在函数定义中声明默认值,则无法忽略一个参数并在其后覆盖一个参数。
If I have a method that can accept varying numbers of parameters, and parameters of varying types, I often declare the function similar to the answer shown by Ryan P.
如果我有一个方法可以接受不同数量的参数和不同类型的参数,我通常会声明类似于Ryan P所显示的功能。
Here is another example (this doesn't answer your question, but is hopefully informative:
这是另一个例子(这并没有回答你的问题,但希望能提供信息:
public function __construct($params = null)
{
if ($params instanceof SOMETHING) {
// single parameter, of object type SOMETHING
} else if (is_string($params)) {
// single argument given as string
} else if (is_array($params)) {
// params could be an array of properties like array('x' => 'x1', 'y' => 'y1')
} else if (func_num_args() == 3) {
$args = func_get_args();
// 3 parameters passed
} else if (func_num_args() == 5) {
$args = func_get_args();
// 5 parameters passed
} else {
throw new InvalidArgumentException("Could not figure out parameters!");
}
}
#2
29
Optional arguments only work at the end of a function call. There is no way to specify a value for $y in your function without also specifying $x. Some languages support this via named parameters (VB/C# for example), but not PHP.
可选参数仅在函数调用的末尾有效。要在函数中指定$y的值,必须同时指定$x。有些语言通过命名参数(例如VB/ c#)支持这一点,但PHP不支持。
You can emulate this if you use an associative array for parameters instead of arguments -- i.e.
如果您使用关联数组作为参数而不是参数,您可以模拟这一点—例如。
function foo(array $args = array()) {
$x = !isset($args['x']) ? 'default x value' : $args['x'];
$y = !isset($args['y']) ? 'default y value' : $args['y'];
...
}
Then call the function like so:
然后调用函数如下:
foo(array('y' => 'my value'));
#3
10
It is actually possible:
它实际上是可能的:
foo( 'blah', (new ReflectionFunction('foo'))->getParameters()[1]->getDefaultValue(), 'test');
Whether you would want to do so is another story :)
你是否愿意这样做是另一回事:
UPDATE:
The reasons to avoid this solution are:
避免这种解决方案的原因是:
- it is (arguably) ugly
- (可以说)丑
- it has an obvious overhead.
- 它有明显的开销。
- as the other answers proof, there are alternatives
- 正如其他答案所证明的,还有其他的选择
But it can actually be useful in situations where:
但它在以下情况下是有用的:
- you don't want/can't change the original function.
- 你不想/不能改变原来的函数。
-
you could change the function but:
你可以改变函数,但是:
- using
null
(or equivalent) is not an option (see DiegoDD's comment) - 使用null(或等价的)不是一个选项(参见DiegoDD的注释)
- you don't want to go either with an associative or with
func_num_args()
- 您不希望使用关联或func_num_args()
- your life depends on saving a couple of LOCs
- 你的生命依赖于保存一些即时通讯
- using
About the performance, a very simple test shows that using the Reflection API to get the default parameters makes the function call 25 times slower, while it still takes less than one microsecond. You should know if you can to live with that.
关于性能,一个非常简单的测试表明,使用反射API获取默认参数会使函数调用速度慢25倍,但仍然需要不到1微秒。你应该知道你是否能忍受。
Of course, if you mean to use it in a loop, you should get the default value beforehand.
当然,如果您想在循环中使用它,您应该事先获得默认值。
#4
9
function image(array $img)
{
$defaults = array(
'src' => 'cow.png',
'alt' => 'milk factory',
'height' => 100,
'width' => 50
);
$img = array_merge($defaults, $img);
/* ... */
}
#5
3
The only way I know of doing it is by omitting the parameter. The only way to omit the parameter is to rearrange the parameter list so that the one you want to omit is after the parameters that you HAVE to set. For example:
我知道的唯一的方法是省略参数。省略参数的唯一方法是重新排列参数列表,以便要省略的参数在必须设置的参数之后。
function foo($blah, $y = "some other value", $x = "some value")
Then you can call foo like:
然后你可以像这样称呼foo:
foo("blah", "test");
This will result in:
这将导致:
$blah = "blah";
$y = "test";
$x = "some value";
#6
2
You can't do this directly, but a little code fiddling makes it possible to emulate.
您不能直接执行此操作,但稍加修改代码就可以实现模拟。
function foo($blah, $x = false, $y = false) {
if (!$x) $x = "some value";
if (!$y) $y = "some other value";
// code
}
#7
1
I recently had this problem and found this question and answers. While the above questions work, the problem is that they don't show the default values to IDEs that support it (like PHPStorm).
我最近遇到了这个问题,发现了这个问题和答案。尽管上述问题有效,但问题是它们没有显示支持它的ide的默认值(如PHPStorm)。
if you use null
you won't know what the value would be if you leave it blank.
如果你使用null,你就不知道如果你把它留空,值是多少。
The solution I prefer is to put the default value in the function definition also:
我比较喜欢的解决方案是在函数定义中也加上默认值:
protected function baseItemQuery(BoolQuery $boolQuery, $limit=1000, $sort = [], $offset = 0, $remove_dead=true)
{
if ($limit===null) $limit =1000;
if ($sort===null) $sort = [];
if ($offset===null) $offset = 0;
...
The only difference is that I need to make sure they are the same - but I think that's a small price to pay for the additional clarity.
唯一的区别是,我需要确保它们是相同的——但我认为,为了增加清晰度,这是一个很小的代价。
#8
0
This is case, when object are better - because you can set up your object to hold x and y , set up defaults etc.
这种情况下,当对象更好时——因为你可以设置对象来保存x和y,设置默认值等等。
Approach with array is near to create object ( In fact, object is bunch of parameters and functions which will work over object, and function taking array will work over some bunch ov parameters )
数组的方法接近于创建对象(实际上,对象是一堆参数和函数,它们将处理对象,函数接收数组将处理一些ov参数)
Cerainly you can always do some tricks to set null or something like this as default
当然,您可以使用一些技巧将null或类似的设置为默认值
#9
0
You can also check if you have an empty string as argument so you can call like:
你也可以检查你是否有一个空字符串作为参数,这样你可以像:
foo('blah', "", 'non-default y value', null);
foo('blah', "", 'non-default y value', null);
Below the function:
以下功能:
function foo($blah, $x = null, $y = null, $z = null) {
if (null === $x || "" === $x) {
$x = "some value";
}
if (null === $y || "" === $y) {
$y = "some other value";
}
if (null === $z || "" === $z) {
$z = "some other value";
}
code here!
}
It doesn't matter if you fill null
or ""
, you will still get the same result.
不管你是否填入null或"" ",你仍然会得到相同的结果。
#1
119
I would propose changing the function declaration as follows so you can do what you want:
我建议将功能声明更改如下,以便您可以做您想做的:
function foo($blah, $x = null, $y = null) {
if (null === $x) {
$x = "some value";
}
if (null === $y) {
$y = "some other value";
}
code here!
}
This way, you can make a call like foo('blah', null, 'non-default y value');
and have it work as you want, where the second parameter $x
still gets its default value.
这样,您可以调用foo('blah', null, 'non-default y value');如果第二个参数$x仍然得到它的默认值,那么它就可以按照您的要求工作。
With this method, passing a null value means you want the default value for one parameter when you want to override the default value for a parameter that comes after it.
通过这个方法,传递一个空值意味着当您想要覆盖一个参数的默认值时,您需要一个参数的默认值。
As stated in other answers,
如其他答案所述,
default parameters only work as the last arguments to the function. If you want to declare the default values in the function definition, there is no way to omit one parameter and override one following it.
默认参数仅作为函数的最后一个参数。如果希望在函数定义中声明默认值,则无法忽略一个参数并在其后覆盖一个参数。
If I have a method that can accept varying numbers of parameters, and parameters of varying types, I often declare the function similar to the answer shown by Ryan P.
如果我有一个方法可以接受不同数量的参数和不同类型的参数,我通常会声明类似于Ryan P所显示的功能。
Here is another example (this doesn't answer your question, but is hopefully informative:
这是另一个例子(这并没有回答你的问题,但希望能提供信息:
public function __construct($params = null)
{
if ($params instanceof SOMETHING) {
// single parameter, of object type SOMETHING
} else if (is_string($params)) {
// single argument given as string
} else if (is_array($params)) {
// params could be an array of properties like array('x' => 'x1', 'y' => 'y1')
} else if (func_num_args() == 3) {
$args = func_get_args();
// 3 parameters passed
} else if (func_num_args() == 5) {
$args = func_get_args();
// 5 parameters passed
} else {
throw new InvalidArgumentException("Could not figure out parameters!");
}
}
#2
29
Optional arguments only work at the end of a function call. There is no way to specify a value for $y in your function without also specifying $x. Some languages support this via named parameters (VB/C# for example), but not PHP.
可选参数仅在函数调用的末尾有效。要在函数中指定$y的值,必须同时指定$x。有些语言通过命名参数(例如VB/ c#)支持这一点,但PHP不支持。
You can emulate this if you use an associative array for parameters instead of arguments -- i.e.
如果您使用关联数组作为参数而不是参数,您可以模拟这一点—例如。
function foo(array $args = array()) {
$x = !isset($args['x']) ? 'default x value' : $args['x'];
$y = !isset($args['y']) ? 'default y value' : $args['y'];
...
}
Then call the function like so:
然后调用函数如下:
foo(array('y' => 'my value'));
#3
10
It is actually possible:
它实际上是可能的:
foo( 'blah', (new ReflectionFunction('foo'))->getParameters()[1]->getDefaultValue(), 'test');
Whether you would want to do so is another story :)
你是否愿意这样做是另一回事:
UPDATE:
The reasons to avoid this solution are:
避免这种解决方案的原因是:
- it is (arguably) ugly
- (可以说)丑
- it has an obvious overhead.
- 它有明显的开销。
- as the other answers proof, there are alternatives
- 正如其他答案所证明的,还有其他的选择
But it can actually be useful in situations where:
但它在以下情况下是有用的:
- you don't want/can't change the original function.
- 你不想/不能改变原来的函数。
-
you could change the function but:
你可以改变函数,但是:
- using
null
(or equivalent) is not an option (see DiegoDD's comment) - 使用null(或等价的)不是一个选项(参见DiegoDD的注释)
- you don't want to go either with an associative or with
func_num_args()
- 您不希望使用关联或func_num_args()
- your life depends on saving a couple of LOCs
- 你的生命依赖于保存一些即时通讯
- using
About the performance, a very simple test shows that using the Reflection API to get the default parameters makes the function call 25 times slower, while it still takes less than one microsecond. You should know if you can to live with that.
关于性能,一个非常简单的测试表明,使用反射API获取默认参数会使函数调用速度慢25倍,但仍然需要不到1微秒。你应该知道你是否能忍受。
Of course, if you mean to use it in a loop, you should get the default value beforehand.
当然,如果您想在循环中使用它,您应该事先获得默认值。
#4
9
function image(array $img)
{
$defaults = array(
'src' => 'cow.png',
'alt' => 'milk factory',
'height' => 100,
'width' => 50
);
$img = array_merge($defaults, $img);
/* ... */
}
#5
3
The only way I know of doing it is by omitting the parameter. The only way to omit the parameter is to rearrange the parameter list so that the one you want to omit is after the parameters that you HAVE to set. For example:
我知道的唯一的方法是省略参数。省略参数的唯一方法是重新排列参数列表,以便要省略的参数在必须设置的参数之后。
function foo($blah, $y = "some other value", $x = "some value")
Then you can call foo like:
然后你可以像这样称呼foo:
foo("blah", "test");
This will result in:
这将导致:
$blah = "blah";
$y = "test";
$x = "some value";
#6
2
You can't do this directly, but a little code fiddling makes it possible to emulate.
您不能直接执行此操作,但稍加修改代码就可以实现模拟。
function foo($blah, $x = false, $y = false) {
if (!$x) $x = "some value";
if (!$y) $y = "some other value";
// code
}
#7
1
I recently had this problem and found this question and answers. While the above questions work, the problem is that they don't show the default values to IDEs that support it (like PHPStorm).
我最近遇到了这个问题,发现了这个问题和答案。尽管上述问题有效,但问题是它们没有显示支持它的ide的默认值(如PHPStorm)。
if you use null
you won't know what the value would be if you leave it blank.
如果你使用null,你就不知道如果你把它留空,值是多少。
The solution I prefer is to put the default value in the function definition also:
我比较喜欢的解决方案是在函数定义中也加上默认值:
protected function baseItemQuery(BoolQuery $boolQuery, $limit=1000, $sort = [], $offset = 0, $remove_dead=true)
{
if ($limit===null) $limit =1000;
if ($sort===null) $sort = [];
if ($offset===null) $offset = 0;
...
The only difference is that I need to make sure they are the same - but I think that's a small price to pay for the additional clarity.
唯一的区别是,我需要确保它们是相同的——但我认为,为了增加清晰度,这是一个很小的代价。
#8
0
This is case, when object are better - because you can set up your object to hold x and y , set up defaults etc.
这种情况下,当对象更好时——因为你可以设置对象来保存x和y,设置默认值等等。
Approach with array is near to create object ( In fact, object is bunch of parameters and functions which will work over object, and function taking array will work over some bunch ov parameters )
数组的方法接近于创建对象(实际上,对象是一堆参数和函数,它们将处理对象,函数接收数组将处理一些ov参数)
Cerainly you can always do some tricks to set null or something like this as default
当然,您可以使用一些技巧将null或类似的设置为默认值
#9
0
You can also check if you have an empty string as argument so you can call like:
你也可以检查你是否有一个空字符串作为参数,这样你可以像:
foo('blah', "", 'non-default y value', null);
foo('blah', "", 'non-default y value', null);
Below the function:
以下功能:
function foo($blah, $x = null, $y = null, $z = null) {
if (null === $x || "" === $x) {
$x = "some value";
}
if (null === $y || "" === $y) {
$y = "some other value";
}
if (null === $z || "" === $z) {
$z = "some other value";
}
code here!
}
It doesn't matter if you fill null
or ""
, you will still get the same result.
不管你是否填入null或"" ",你仍然会得到相同的结果。