如何在函数调用中跳过可选参数?
好吧,我完全忘记了如何在 PHP 中跳过参数。
假设我有:
function getData($name, $limit = '50', $page = '1') {
...
}
我如何调用这个函数以便中间参数采用默认值(即“50”)?
getData('some name', '', '23');
上面的说法正确吗? 我似乎无法让它发挥作用。
OK I totally forgot how to skip arguments in PHP.
Lets say I have:
function getData($name, $limit = '50', $page = '1') {
...
}
How would I call this function so that the middle parameter takes the default value (ie. '50')?
getData('some name', '', '23');
Would the above be correct? I can't seem to get this to work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(21)
你的帖子是正确的。
不幸的是,如果您需要在参数列表的最后使用可选参数,则必须指定最后一个参数之前的所有内容。 通常,如果您想混合搭配,可以为它们指定默认值
''
或null
,如果它们是默认值,则不要在函数内使用它们价值。Your post is correct.
Unfortunately, if you need to use an optional parameter at the very end of the parameter list, you have to specify everything up until that last parameter. Generally if you want to mix-and-match, you give them default values of
''
ornull
, and don't use them inside the function if they are that default value.不,不可能以这种方式跳过参数。 仅如果参数位于参数列表的末尾,则可以省略它们的传递。
有一个官方提案:https://wiki.php.net/rfc/skipparams,但遭到拒绝。 提案页面链接到有关此主题的其他 SO 问题。
Nope, it's not possible to skip arguments this way. You can omit passing arguments only if they are at the end of the parameter list.
There was an official proposal for this: https://wiki.php.net/rfc/skipparams, which got declined. The proposal page links to other SO questions on this topic.
除了指定
false
或null
等默认值之外,没有其他方法可以“跳过”参数。由于 PHP 在这方面缺乏一些语法糖,因此您经常会看到类似这样的内容:
正如注释中雄辩地说的那样,它正在使用数组来模拟命名参数。
这提供了最大的灵活性,但在某些情况下可能不需要。 至少,您可以将您认为大多数情况下不需要的内容移至参数列表的末尾。
There's no way to "skip" an argument other than to specify a default like
false
ornull
.Since PHP lacks some syntactic sugar when it comes to this, you will often see something like this:
Which, as eloquently said in the comments, is using arrays to emulate named arguments.
This gives ultimate flexibility but may not be needed in some cases. At the very least you can move whatever you think is not expected most of the time to the end of the argument list.
该功能在 PHP 8.0 中实现
其中:
文档供参考
无需更改即可使用此功能:
让我们使用 OP 函数
function getData($name, $limit = '50', $page = '1')
用法
本机函数也会使用此功能
Netbeans支持 IDE 12.3 功能
此功能受支持,但命名参数的代码完成除外,看起来更好;)
This feature is implemented in PHP 8.0
which:
The documentation for reference
No changes necessary to use this feature:
lets use OPs function
function getData($name, $limit = '50', $page = '1')
Usage
Native functions will also use this feature
Netbeans IDE 12.3 Feature Supported
This feature is supported, with the exception of code completion for named arguments, looks better ;)
关于能够跳过可选参数没有任何改变,但是为了正确的语法并能够为我想跳过的参数指定 NULL,我将这样做:
这可以这样调用:
getData( 'some name',NULL,'23');
并且将来调用该函数的任何人都不需要每次都记住默认值或为他们声明的常量。Nothing has changed regarding being able to skip optional arguments, however for correct syntax and to be able to specify NULL for arguments that I want to skip, here's how I'd do it:
This can the be called thusly:
getData('some name',NULL,'23');
and anyone calling the function in future need not remember the defaults every time or the constant declared for them.简单的答案是否。 但为什么在重新排列参数时要跳过呢?
您的问题是“默认函数参数的错误使用”,并且不会按您的预期工作。
PHP 文档的旁注:
考虑以下内容:
输出将是:
默认函数参数的正确用法应该是这样的:
输出将是:
将默认值放在非默认值之后的右侧,确保它将始终重新调整该变量的默认值如果没有定义/给出
这是一个链接供参考以及这些示例的来源。
编辑:将其设置为
null
正如其他人建议的那样可能有效,并且是另一种选择,但可能不适合您想要的。 如果未定义,它将始终将默认值设置为 null。The simple answer is No. But why skip when re-arranging the arguments achieves this?
Yours is an "Incorrect usage of default function arguments" and will not work as you expect it to.
A side note from the PHP documentation:
Consider the following:
The output will be:
The Correct usage of default function arguments should be like this:
The output will be:
Putting the default on your right after the non-defaults makes sure that it will always retun the default value for that variable if its not defined/given
Here is a link for reference and where those examples came from.
Edit: Setting it to
null
as others are suggesting might work and is another alternative, but may not suite what you want. It will always set the default to null if it isn't defined.为了安全起见,对于跳过的任何参数(您必须)使用默认参数。
(在默认参数为 '' 或类似参数的情况下设置为 null,反之亦然会给您带来麻烦......)
For any parameter skipped (you have to) go with the default parameter, to be on the safe side.
(Settling for null where the default parameter is '' or similar or vice versa will get you into troublew...)
你不能跳过参数,但可以使用数组参数,并且只需要定义 1 个参数,即参数数组。
并且你可以添加所需数量的参数,不需要来定义它们。 当您调用该函数时,您可以像这样输入参数:
You can't skip arguments but you can use array parameters and you need to define only 1 parameter, which is an array of parameters.
And you can add as many parameters you need, you don't need to define them. When you call the function, you put your parameters like this:
如上所述,您将无法跳过参数。 我写这个答案是为了提供一些附录,该附录太大而无法放在评论中。
@Frank Nocke 建议使用默认参数调用该函数,因此例如让
您应该使用
它在功能上是相同的省略前两个(
$b
和$c
)参数。目前尚不清楚哪些是默认值(输入
0
是为了提供默认值,还是很重要?)。当函数(或方法)作者可以更改默认值时,还存在默认值问题与外部(或内置)函数相关的危险。 因此,如果您不更改程序中的调用,则可能会无意中更改其行为。
一些解决方法可能是定义一些全局常量,例如 DEFAULT_A_B ,这将是“函数 A 的 B 参数的默认值”并以这种方式“省略”参数:
对于类,如果您定义类常量,因为它们是全局范围的一部分,例如。
请注意,此默认常量在整个代码中仅定义一次(即使在方法声明中也没有值),因此,如果发生一些意外更改,您将始终为函数/方法提供正确的默认值。
这个解决方案的清晰度当然比提供对读者没有任何影响的原始默认值(如 NULL 、 0 等)要好。
(我同意像
$var = a(,,'ddd');
这样的调用将是最好的选择)As mentioned above, you will not be able to skip parameters. I've written this answer to provide some addendum, which was too large to place in a comment.
@Frank Nocke proposes to call the function with its default parameters, so for example having
you should use
which will functionally be the same as omitting the first two (
$b
and$c
) parameters.It is not clear which ones are defaults (is
0
typed to provide default value, or is it important?).There is also a danger that default values problem is connected to external (or built-in) function, when the default values could be changed by function (or method) author. So if you wouldn't change your call in the program, you could unintentionally change its behaviour.
Some workaround could be to define some global constants, like
DEFAULT_A_B
which would be "default value of B parameter of function A" and "omit" parameters this way:For classes it is easier and more elegant if you define class constants, because they are part of global scope, eg.
Note that this default constant is defined exactly once throughout the code (there is no value even in method declaration), so in case of some unexpected changes, you will always supply the function/method with correct default value.
The clarity of this solution is of course better than supplying raw default values (like
NULL
,0
etc.) which say nothing to a reader.(I agree that calling like
$var = a(,,'ddd');
would be the best option)我必须创建一个具有可选参数的工厂,我的解决方法是使用空合并运算符:
用法:
不是最漂亮的东西,但可能是在工厂中用于测试的一个很好的模式。
I had to make a Factory with optional parameters, my workaround was to use the null coalescing operator:
Usage:
Not the prettiest thing, but might be a good pattern to use in Factories for tests.
正如其他人已经说过的,如果不在函数中添加任何代码行,您想要的东西在 PHP 中是不可能实现的。
但是您可以将这段代码放在函数的顶部来获取您的功能:
所以基本上使用
debug_backtrace()
我获取此代码所在的函数名称,然后创建一个新的ReflectionFunction
对象并循环遍历所有函数参数。在循环中,我只需检查函数参数是否为
empty()
并且该参数是“可选的”(意味着它有一个默认值)。 如果是,我只需将默认值分配给参数即可。演示
Well as everyone else already said, that what you want won't be possible in PHP without adding any code lines in the function.
But you can place this piece of code at the top of a function to get your functionality:
So basically with
debug_backtrace()
I get the function name in which this code is placed, to then create a newReflectionFunction
object and loop though all function arguments.In the loop I simply check if the function argument is
empty()
AND the argument is "optional" (means it has a default value). If yes I simply assign the default value to the argument.Demo
请将限制设置为 null
并调用该函数
如果您想设置可以作为参数传递的限制,
Set the limit to null
and call to that function
if you want to set the limit you can pass as an argument
正如之前所建议的,没有任何变化。
但请注意,太多参数(尤其是可选参数)是代码异味的强烈指标。
也许你的函数做得太多了:
一些参数可以按逻辑分组:
在最后的手段中,你总是可以引入一个临时的 参数对象:(
这只是不太正式的参数数组 技术)
有时,使参数可选的原因本身就是错误的。 在这个例子中,
$page
真的是可选的吗? 保存几个角色真的会有所不同吗?As advised earlier, nothing changed.
Beware, though, too many parameters (especially optional ones) is a strong indicator of code smell.
Perhaps your function is doing too much:
Some parameters could be grouped logically:
In last resort, you can always introduce an ad-hoc parameter object:
(which is just a glorified version of the less formal parameter array technique)
Sometimes, the very reason for making a parameter optional is wrong. In this example, is
$page
really meant to be optional? Does saving a couple of characters really make a difference?这段代码:
答案是:
This snippet:
Answer is :
这就是我要做的:
希望这能帮助别人
This is what I would do:
Hope this will help someone
这是一个古老的问题,有许多技术上可行的答案,但它需要 PHP 中的现代设计模式之一:面向对象编程。 不要注入原始标量数据类型的集合,而是考虑使用包含函数所需的所有数据的“注入对象”。
http://php.net/manual/en/language.types.intro。 php
注入对象可能具有属性验证例程等。如果实例化和向注入对象注入数据无法通过所有验证,则代码可以立即抛出异常,应用程序可以避免处理可能不完整的数据的尴尬过程。
我们可以在部署之前对注入的对象进行类型提示以捕获错误。 这篇文章总结了几年前的一些想法。
https://www. Experts-exchange.com/articles/18409/Using-Named-Parameters-in-PHP-Function-Calls.html
This is kind of an old question with a number of technically competent answers, but it cries out for one of the modern design patterns in PHP: Object-Oriented Programming. Instead of injecting a collection of primitive scalar data types, consider using an "injected-object" that contains all of the data needed by the function.
http://php.net/manual/en/language.types.intro.php
The injected-object may have property validation routines, etc. If the instantiation and injection of data into the injected-object is unable to pass all of the validation, the code can throw an exception immediately and the application can avoid the awkward process of dealing with potentially incomplete data.
We can type-hint the injected-object to catch mistakes before deployment. Some of the ideas are summarized in this article from a few years ago.
https://www.experts-exchange.com/articles/18409/Using-Named-Parameters-in-PHP-Function-Calls.html
从 PHP 8.0.0 开始,不推荐在可选参数之后声明强制参数。
您现在可以省略可选参数。
例子:
As of PHP 8.0.0, declaring mandatory arguments after optional arguments is deprecated.
You can now omit optional parameters.
Example:
您不能跳过函数调用中的中间参数。 但是,您可以使用以下方法解决:
功能:
You can not skip middle parameter in your function call. But, you can work around with this:
Function:
尝试这个。
Try This.
正如@IbrahimLawal 指出的。 最佳实践是将它们设置为
null
值。 只需检查传递的值是否为null
,其中您使用定义的默认值。希望这可以帮助。
As @IbrahimLawal pointed out. It's best practice to just set them to
null
values. Just check if the value passed isnull
in which you use your defined defaults.Hope this helps.
只是不要通过它们,默认值将被接受
just do not pass them and the default value will be accepted