Php 如何跳过函数调用中的可选参数?

Php 如何跳过函数调用中的可选参数?,php,function,parameters,default-value,optional-parameters,Php,Function,Parameters,Default Value,Optional Parameters,好的,我完全忘记了如何在PHP中跳过参数 假设我有: function getData($name, $limit = '50', $page = '1') { ... } 我该如何调用此函数,以便中间的参数采用默认值(即“50”) 以上是正确的吗?我好像没法让它工作。你的帖子是正确的 不幸的是,如果您需要在参数列表的最后使用一个可选参数,那么您必须指定直到最后一个参数为止的所有内容。通常,如果要混合和匹配,可以为它们指定默认值'或null,如果它们是默认值,则不要在函数中使用它们。除

好的,我完全忘记了如何在PHP中跳过参数

假设我有:

function getData($name, $limit = '50', $page = '1') {
    ...
}
我该如何调用此函数,以便中间的参数采用默认值(即“50”)

以上是正确的吗?我好像没法让它工作。

你的帖子是正确的

不幸的是,如果您需要在参数列表的最后使用一个可选参数,那么您必须指定直到最后一个参数为止的所有内容。通常,如果要混合和匹配,可以为它们指定默认值
'
null
,如果它们是默认值,则不要在函数中使用它们。

除了指定默认值(如
false
null
)之外,没有办法“跳过”参数

由于PHP在这方面缺乏一些语法上的优势,您经常会看到这样的情况:

checkbox_field(array(
    'name' => 'some name',
    ....
));
myfunction(array("name" => "Bob","age" => "18", .........));
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
正如在评论中雄辩地说的那样,它使用数组来模拟命名参数

这提供了最大的灵活性,但在某些情况下可能不需要。至少,您可以在大多数情况下将您认为不需要的任何内容移动到参数列表的末尾。

为安全起见,跳过的任何参数(您必须)使用默认参数


(如果默认参数为“”或类似参数,则设置为null,反之亦然,将使您陷入困境…

不,不可能以这种方式跳过参数。仅当传递的参数位于参数列表的末尾时,才可以省略它们


对此有一个官方提案,但遭到拒绝。“建议”页面链接到此主题的其他SO问题。

您不能跳过参数,但可以使用数组参数,只需定义一个参数,即参数数组。

function myfunction($array_param)
{
    echo $array_param['name'];
    echo $array_param['age'];
    .............
}
您可以添加所需的任意多个参数,而无需定义它们。调用该函数时,将参数如下所示:

checkbox_field(array(
    'name' => 'some name',
    ....
));
myfunction(array("name" => "Bob","age" => "18", .........));
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

如上所述,您将无法跳过参数。我写这个答案是为了提供一些附录,因为附录太大,无法放在评论中

@Frank Nocke使用其默认参数调用函数,例如

function a($b=0, $c=NULL, $d=''){ //...
你应该使用

$var = a(0, NULL, 'ddd'); 
这在功能上与省略前两个(
$b
$c
)参数相同

不清楚哪些是默认值(键入
0
是为了提供默认值,还是重要?)

当函数(或方法)作者可以更改默认值时,默认值问题也可能与外部(或内置)函数有关。因此,如果您不在程序中更改调用,您可能会无意中更改其行为

一些解决方法可以是定义一些全局常量,如
DEFAULT\u A\u 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');
这样的调用是最好的选择)

正如其他人所说,如果不在函数中添加任何代码行,在PHP中就不可能实现您想要的功能

但您可以将这段代码放在函数的顶部,以获得您的功能:

foreach((new ReflectionFunction(debug_backtrace()[0]["function"]))->getParameters() as $param) {
    if(empty(${$param->getName()}) && $param->isOptional())
        ${$param->getName()} = $param->getDefaultValue();
}
基本上,我得到了放置代码的函数名,然后创建一个新的对象并循环所有函数参数

在循环中,我只需检查函数参数是否为,参数是否为“可选”(表示它有一个默认值)。如果是,我只是将默认值指定给参数

将限制设置为空

function getData($name, $limit = null, $page = '1') {
    ...
}
并调用该函数

getData('some name', null, '23');
如果要设置限制,可以将其作为参数传递

getData('some name', 50, '23');

关于能够跳过可选参数,没有任何变化,但是为了正确语法和能够为我要跳过的参数指定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('somename',NULL,'23')
和以后调用该函数的任何人都不必每次都记住默认值或为其声明的常量

getData('some name');
只要不传递它们,默认值就会被接受

试试这个

function getData($name, $limit = NULL, $page = '1') {
               if (!$limit){
                 $limit = 50;
               }
}

getData('some name', '', '23');

不能跳过函数调用中的中间参数。但是,您可以解决以下问题:

function_call('1', '2', '3'); // Pass with parameter.
function_call('1', null, '3'); // Pass without parameter.
功能:

function function_call($a, $b='50', $c){
    if(isset($b)){
        echo $b;
    }
    else{
        echo '50';
    }
}
,没有改变。 但是要注意,太多的参数(尤其是可选参数)是代码气味的强烈指示器

也许您的功能做得太多了:

// first build context
$dataFetcher->setPage(1);
// $dataFetcher->setPageSize(50); // not used here
// then do the job
$dataFetcher->getData('some name');
某些参数可以按逻辑分组:

$pagination = new Pagination(1 /*, 50*/);
getData('some name', $pagination);
// Java coders will probably be familiar with this form:
getData('some name', new Pagination(1));
在最后一种情况下,您始终可以引入一种特别的:

(这只是不太正式的一个美化版本)

有时,将参数设置为可选参数的原因是错误的。在本例中,
$page
真的是可选的吗?保存几个角色真的会有不同吗

// dubious
// it is not obvious at first sight that a parameterless call to "getData()"
// returns only one page of data
function getData($page = 1);

// this makes more sense
function log($message, $timestamp = null /* current time by default */);

正如@IbrahimLawal指出的那样。最好将它们设置为
null
值。只需检查传递的值是否为
null
,在该值中使用您定义的默认值

<?php
define('DEFAULT_LIMIT', 50);
define('DEFAULT_PAGE', 1);

function getData($name, $limit = null, $page = null) {
    $limit = is_null($limit) ? DEFAULT_LIMIT : $limit;
    $page = is_null($page) ? DEFAULT_PAGE : $page;
    ...
}
?>


希望这能有所帮助。

简单的答案是。但是,当重新安排论点时,为什么要跳过呢

您的问题是“默认函数参数的用法不正确”,无法按预期工作

PHP文档中的旁注:

使用默认参数时,任何
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"
function getData($name, $options) { $default = array( 'limit' => 50, 'page' => 2, ); $args = array_merge($default, $options); print_r($args); } getData('foo', array()); getData('foo', array('limit'=>2)); getData('foo', array('limit'=>10, 'page'=>10)); Array ( [limit] => 50 [page] => 2 ) Array ( [limit] => 2 [page] => 2 ) Array ( [limit] => 10 [page] => 10 )
<?php

    function getData($name, $limit = '', $page = '1') {
            $limit = (EMPTY($limit)) ? 50 : $limit;
            $output = "name=$name&limit=$limit&page=$page";
            return $output;
    }

     echo getData('table');

    /* output name=table&limit=50&page=1 */

     echo getData('table',20);

    /* name=table&limit=20&page=1 */

    echo getData('table','',5);

    /* output name=table&limit=50&page=5 */

    function getData2($name, $limit = NULL, $page = '1') {
            $limit = (ISSET($limit)) ? $limit : 50;
            $output = "name=$name&limit=$limit&page=$page";
            return $output;
    }

    echo getData2('table');

    // /* output name=table&limit=50&page=1 */

    echo getData2('table',20);

    /* output name=table&limit=20&page=1 */

    echo getData2('table',NULL,3);

    /* output name=table&limit=50&page=3 */

?>
public static function make(
    string $first_name = null,
    string $last_name = null,
    string $email = null,
    string $subject = null,
    string $message = null
) {
    $first_name = $first_name ?? 'First';
    $last_name  = $last_name ?? 'Last';
    $email      = $email ?? 'foo@bar.com';
    $subject    = $subject ?? 'Some subject';
    $message    = $message ?? 'Some message';
}
$factory1 = Factory::make('First Name Override');
$factory2 = Factory::make(null, 'Last Name Override');
$factory3 = Factory::make(null, null, null, null 'Message Override');