繁体   English   中英

PHP函数具有可选参数但允许空值(和类似值)?

[英]PHP functions that have optional arguments but allow null (and similar) values?

我知道您可以使用带有可选参数的PHP函数,如下所示:

function do_something($argument = null) 
{
   // argument not provided
   if ($argument === null) 
      ........
}

考虑null / false和其他值都是我的函数的有效参数的情况。 如何确定是否提供了论点?

do_something(null);            // argument provided
do_something(false);           // argument provided
do_something(0);               // argument provided
do_something("test");          // argument provided
do_something(new stdClass());  // argument provided
do_something();                // nothing provided

我如何发现最后一种情况? 我曾考虑过使用func_num_args在大多数情况下都可以使用,但如果我有几个可选参数,则无法使用。

有什么可以解决这个问题的吗?

func_num_args()应该完全按照您希望的方式工作,因为您可能会假设实际上并非如此:如果可选参数位于参数列表的中间,则不能忽略它们。

因此,让我们看一下这个函数:

function test1 ($param1 = null, $param2 = null) {
   return func_num_args();
}

如果使用不同的参数组合调用它,则会得到以下结果:

test1()              => 0
test1(true)          => 1
test1(true, true)    => 2

根本没有办法以设置$param2而不设置$param1方式调用函数。 因此,您可以将func_num_args()所有可能的输出映射到恰好一个参数配置。

在上面的示例中,您可以依靠以下事实:

  • 如果返回值为1 ,则肯定没有设置$param2 ,而设置了$param1
  • 对于0则100%确保没有给出任何一个。
  • 而且,当然,如果两者均为2

您实际需要的是命名参数,因为许多其他语言也有它们。 PHP目前没有。 NikiC实际上写了一个RFC,建议在PHP中添加命名参数,但是我认为将来仍然遥遥无期。 您可以在这里查看: https : //wiki.php.net/rfc/named_pa​​rams

由于这些尚不可用,因此您可以尝试以下几种解决方法:

解决方法1

如果确实需要所有参数都是可选的,请尝试使用参数数组:

function test1 (array $opts) {
    if (!isset($opts['opt1'])) { $opts['opt1'] = 'default1'; }
    if (!isset($opts['opt2'])) { $opts['opt2'] = 'default2'; }
}

然后您可以这样称呼它:

test1(array('opt2' => true))

它将第一个参数设置为“ default1”,同时保留第二个参数。 确实有更好,更优雅的方法(例如,使用对象代替),但是总体思路是相同的。

解决方法2

您还可以使用别名功能:

function test ($param1, $patam2) { ... ]
function testNoParam1 ($param2) {
    test("default1", $param2);
}

至少这使得它很容易阅读,但是当然您需要根据所拥有的参数选择正确的功能。

解决方法3

通过添加许多其他代码,您可以真正喜欢上并使用FactoryObject:

class FunctionExecutor {
    private $param1 = "default1";
    private $param2 = "default2";

    public function param1($val) {
       $this->param1 = $val;
       return $this;
    }

    public function param2($val) {
       $this->param2 = $val;
       return $this;
    }

    public function execute() {
       return yourFunction($this->param1, $this->param2);
    }
}

可以这样使用:

$doSomething = new FunctionExecutor();
$returnValue = $doSomething->param2(42)->execute();

在这种方法中,将函数实际放入对象而不是全局定义它可能是一个更好的主意。 无论如何……这绝对是一种可能,但不是最实际的一种。 只是想添加它,因为它有一些好处。

也许这会有所帮助: http : //www.php.net//manual/en/function.func-get-args.php

$args = func_get_args();
if(!isset($arg[0])) {
    echo 'no argument';
}

要么

isset(func_get_arg(0));

传递“ null”,“ 0”或“ false”表示您分配内存以存储变量,无论变量的范围,类型或大小如何。 然后将其用作函数的参数。

在PHP中,不能通过参数覆盖函数,但是可以通过调用“ func_get_args()”来访问它们,这是处理传递给函数的不同数量/类型的参数的唯一方法:

function do_something() {
 $args = func_get_args();

 //do_something(stdClass, 1)
 if($args[0] instanceof stdClass && is_numeric($args[1])) {
     //handle
     //return 

 //do_something(1, "string")
 } else if(is_numeric($args[0]) && is_string($args[1])) {
     //handle
     //return
 }
 throw new Exception('invalid arguments');
}

do_something(new StdClass(), 100); //ok
do_something(100, "hell world") // ok
do_someting(); //throws Exception('invalid arguments');

在PHP 7中,您可以执行以下操作:

function action(...$args) {
    if (count($args) === 0) {
        return action_default();
    }
    $var1 = array_shift($args);
    $var2 = array_shift($args);
    $var3 = array_shift($args);
    // etc.
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM