好的,我完全忘记了如何在PHP中跳过参数。
假设我有以下代码:
function getData($name, $limit = '50', $page = '1') {
...
}
我该如何调用这个函数,使得中间的参数采用默认值(即 '50')?getData('some name', '', '23');
以上的代码是否正确?我似乎无法让它工作。
好的,我完全忘记了如何在PHP中跳过参数。
假设我有以下代码:
function getData($name, $limit = '50', $page = '1') {
...
}
我该如何调用这个函数,使得中间的参数采用默认值(即 '50')?getData('some name', '', '23');
以上的代码是否正确?我似乎无法让它工作。
您的帖子是正确的。
不幸的是,如果您需要在参数列表的最后使用可选参数,则必须指定该参数之前的所有内容。通常,如果您想混合和匹配,可以将它们的默认值设置为''
或null
,如果它们是这个默认值,则不在函数内使用。
不,不能用这种方式跳过参数。您只能在参数列表末尾省略传递参数。
曾经有一个正式的提案:https://wiki.php.net/rfc/skipparams,但被拒绝了。该提案页面链接到其他关于此主题的SO问题。
除了指定像false
或null
这样的默认值之外,没有其他方法可以“跳过”参数。
由于PHP在这方面缺乏一些语法糖,因此您经常会看到类似于以下内容:
checkbox_field(array(
'name' => 'some name',
....
));
正如评论中所 eloquently 说的那样,这是使用数组来模拟命名参数。
这提供了终极的灵活性,但在某些情况下可能不需要。至少,您可以将您认为大多数情况下不被期望的任何内容移动到参数列表的末尾。
这个功能是在PHP8.0中实现的
PHP 8引入了命名参数
它:
允许任意跳过默认值
参考文档
让我们使用OP的函数 function getData($name, $limit = '50', $page = '1')
用法
getData(name: 'some name', page: '23');
htmlspecialchars($string, double_encode: false);
// Same as
htmlspecialchars($string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
除了对命名参数的代码补全外,该功能得到支持,看起来更好 ;)
关于跳过可选参数,没有任何变化,但为了正确的语法和能够指定NULL作为要跳过的参数,以下是我会这样做:
define('DEFAULT_DATA_LIMIT', '50');
define('DEFAULT_DATA_PAGE', '1');
/**
* getData
* get a page of data
*
* Parameters:
* name - (required) the name of data to obtain
* limit - (optional) send NULL to get the default limit: 50
* page - (optional) send NULL to get the default page: 1
* Returns:
* a page of data as an array
*/
function getData($name, $limit = NULL, $page = NULL) {
$limit = ($limit===NULL) ? DEFAULT_DATA_LIMIT : $limit;
$page = ($page===NULL) ? DEFAULT_DATA_PAGE : $page;
...
}
getData('某个名称',NULL,'23');
以后任何调用该函数的人都不需要每次都记住默认值或为它们声明的常量。function getData($name, $limit = '50', $page = '1') {
return "Select * FROM books WHERE name = $name AND page = $page limit $limit";
}
echo getData('some name', '', '23'); // won't work as expected
"Select * FROM books WHERE name = some name AND page = 23 limit"
function getData($name, $page = '1', $limit = '50') {
return "Select * FROM books WHERE name = $name AND page = $page limit $limit";
}
echo getData('some name', '23'); // works as expected
"Select * FROM books WHERE name = some name AND page = 23 limit 50"
null
可能有效,也是另一种选择,但可能不适合您想要的情况。它将始终将默认值设置为null(空),如果未定义的话。您不能跳过参数,但可以使用数组参数,并且只需定义1个参数,即参数的数组。
function myfunction($array_param)
{
echo $array_param['name'];
echo $array_param['age'];
.............
}
您可以添加所需的任意数量的参数,无需定义它们。当您调用函数时,将参数放置在以下位置:
myfunction(array("name" => "Bob","age" => "18", .........));
如上所述,您将无法跳过参数。我写这篇答案是为了提供一些补充说明,因为它太大了,无法放在评论中。
@Frank Nocke建议使用默认参数调用函数,例如:
function a($b=0, $c=NULL, $d=''){ //...
你应该使用
$var = a(0, NULL, 'ddd');
这将在功能上与省略前两个参数($b
和$c
)的效果相同。
不清楚哪些是默认值(0
是否提供默认值或者是否很重要?)。
还有一种危险,即默认值问题与外部(或内置)函数相关联,当默认值可能被函数(或方法)作者更改时,就会出现问题。因此,如果您不在程序中更改调用,则可能无意中更改其行为。
一些解决方法可以是定义一些全局常量,例如DEFAULT_A_B
,它将是“函数A的B参数的默认值”,并通过以下方式省略参数:
$var = a(DEFAULT_A_B, DEFAULT_A_C, 'ddd');
对于类来说,如果你定义类常量,那将更加容易和优雅,因为它们是全局范围的一部分,例如:
class MyObjectClass {
const DEFAULT_A_B = 0;
function a($b = self::DEFAULT_A_B){
// method body
}
}
$obj = new MyObjectClass();
$var = $obj->a(MyObjectClass::DEFAULT_A_B); //etc.
NULL
,0
等)更好,这些原始默认值对读者来说毫无意义。$var = a(,,'ddd');
这样的调用将是最佳选项)如果有任何参数被跳过,你需要选择默认参数,以保险起见。
(在默认参数为''或类似情况下选择null,或反之亦然,会让你陷入麻烦...)
https://www.experts-exchange.com/articles/18409/Using-Named-Parameters-in-PHP-Function-Calls.html
ReflectionFunction
传递默认参数。我在类似的问题中发布了答案。 - David