【问题标题】:can php function parameters be passed in different order as defined in declarationphp函数参数可以按照声明中定义的不同顺序传递吗
【发布时间】:2011-01-08 20:51:30
【问题描述】:

假设我有一个函数/方法 F(),它接受定义为 this 的 3 个参数 $A、$B 和 $C。

function F($A,$B,$C){
  ...
}

假设我不想按照顺序传递参数,我可以这样调用吗?

F($C=3,$A=1,$B=1);

而不是

F(1,2,3)

【问题讨论】:

  • 不要误会我的意思,但是当生成的代码完全一团糟时,这有什么意义呢?
  • 想想其他语言,比如 R。你有一个绘图函数,我不知道,>20 个参数。他们都有名字,大多数是可选的,只是数据是强制性的。您可以通过提供一对name = value 来决定提供更多参数来自定义绘图。这不会造成混乱,而且 IMO 非常好。因此,这个问题至少是有道理的。
  • Python 也支持这个。

标签: php


【解决方案1】:

绝对不是。

您可以传入无序参数的一种方法是采用关联数组:

function F($params) {
   if(!is_array($params)) return false;
   //do something with $params['A'], etc...
}

然后你可以像这样调用它:

F(array('C' => 3, 'A' => 1, 'B' => 1));

【讨论】:

  • 你能说为什么不?
  • 在较新版本的 PHP 中,您还可以调用:F(["C" => 3, "A" => 1, "B" => 1]);
  • php@8 将具有命名参数。
【解决方案2】:

不,但你可以传入一个关联数组来处理这个问题:

f(array('C'=>3, 'A'=>1, 'B'=>1));

然后通过以下方式访问它:

function f($obj)
{
   $c = $obj['C'];
}

【讨论】:

  • 你能说为什么不?
【解决方案3】:

PHP 没有命名参数,所以简短的回答是否定的。我可以找到两种解决方案,虽然都不是那么好。

您可以定义您的函数以将其参数作为一个数组,例如 this:

function image($img) {
    $tag  = '<img src="' . $img['src'] . '" ';
    $tag .= 'alt="' . ($img['alt'] ? $img['alt'] : '') .'">';
    return $tag;
}

$image = image(array('src' => 'cow.png', 'alt' => 'cows say moo'));
$image = image(array('src' => 'pig.jpeg'));

不幸的是,该方法需要您修改函数,因此我不喜欢它。另一种选择是使用this wrapper class,它允许您以下列方式之一使用命名参数:

$obj->method(array('key' => 'value', 'key2' => 'value2'));
$obj->method(':key = value', ':key2 = value2');

【讨论】:

    【解决方案4】:

    另一种可能对某些人有用的方法是将单个参数作为带有“关键字”的字符串传递,例如...

        function foo($prms=""){
            isNAKED = (stripos(strtoupper($prms),"NAKED") !== false);
            showDETAILS = preg_match(...AS.NECESSARY...0)
            If (showDETAILS[0]){
               do what you do
            }
        }
    

    那么你的参数可以是任何顺序,可以一起丢失,字母大小写无关紧要。您可以预先决定如何对传递的值进行编码:DETAILS=6 或 DETAILS(6) 或其他任何值。

    因此, foo("NAKED DETAILS(6)") 会起作用,或者 foo("DETAILS(6) NAKED") 会起作用。它也可以与这样的东西一起使用......

    foo("C=3,A=1,B=1");

    或 - foo("C=$C,A=1,B=$SOMETHINGELSEALLTOGETHERDIFFERENT");

    它确实需要代码来解析值

    我发现这在传递(并检测是否存在)关键词(如上面的“NAKED”)时最有效

    【讨论】:

    • 但是为什么要使用它而不是在关联数组中传递参数呢?与仅使用关联数组相比,这似乎是一个过于复杂的解决方案。
    【解决方案5】:

    以php@8开头,php will suppport named arguments

    这将允许以不同的顺序传递参数,只要您在调用时提供它们的名称。

    例如这可能看起来像:

    class SomeDto
    {
        public function __construct(
            public int $foo = 'foo',
            public string $bar = 'bar',
            public string $baz = 'baz',
        ) {}
    }
    
    $example = new SomeDto($bar = 'fnord!');
    // will result in an object { foo: 'foo', bar: 'fnord!', baz: 'baz'}
    

    【讨论】:

      【解决方案6】:

      不,不使用标准 php 语法。

      当然,总有一些技巧,比如如果你自己定义函数,你可以做类似的事情

      F(array('C'=>3, 'A'=>1, 'B'=>1));
      

      但是为此,您当然必须重写原始函数,以便它接受一个数组作为参数,而不是只接受参数本身。

      【讨论】:

        【解决方案7】:

        不,你不能。对于许多参数是可选的或者我不想顺序重要的函数,我所做的事情是使用单个数组参数。

        function myfunc( $options ) {
             $one = $options['one'];
             $two = $options['two'];
             // etc.
        }
        

        【讨论】:

          【解决方案8】:

          取自here...

          如果您更喜欢在函数中使用命名参数(因此您不必担心变量参数列表的顺序),您可以使用匿名数组的 PERL 样式:

          <?php
          function foo($args)
          {
              print "named_arg1 : " . $args["named_arg1"] . "\n";
              print "named_arg2 : " . $args["named_arg2"] . "\n";
          }
          
          foo(array("named_arg1" => "arg1_value", "named_arg2" => "arg2_value"));
          ?>
          

          将输出:

          named_arg1 : arg1_value
          named_arg2 : arg2_value
          

          【讨论】:

            【解决方案9】:

            来自phpsite

            在 PHP 5.6 及更高版本中,参数列表可能包含 ... 标记,以表示函数接受可变数量的参数。参数将作为数组传递给给定的变量;例如:

            <?php
            function sum(...$numbers) {
                $acc = 0;
                foreach ($numbers as $n) {
                    $acc += $n;
                }
                return $acc;
            }
            
            echo sum(1, 2, 3, 4);
            ?>
            

            instanceofis_subclass_of进行后期处理,如here(下):

            class Foo {
            
                public $foobar = 'Foo';
            
                public function test() {
                    echo $this->foobar . "\n";
                }
            
            }
            
            class Bar extends Foo {
            
                public $foobar = 'Bar';
            
            }
            
            $a = new Foo();
            $b = new Bar();
            
            echo "use of test() method\n";
            $a->test();
            $b->test();
            
            echo "instanceof Foo\n";
            var_dump($a instanceof Foo); // TRUE
            var_dump($b instanceof Foo); // TRUE
            
            echo "instanceof Bar\n";
            var_dump($a instanceof Bar); // FALSE
            var_dump($b instanceof Bar); // TRUE
            
            echo "subclass of Foo\n";
            var_dump(is_subclass_of($a, 'Foo')); // FALSE
            var_dump(is_subclass_of($b, 'Foo')); // TRUE
            
            echo "subclass of Bar\n";
            var_dump(is_subclass_of($a, 'Bar')); // FALSE
            var_dump(is_subclass_of($b, 'Bar')); // FALSE
            
            ?>
            
            Result (CLI, 5.4.4):
            
            use of test() method
            Foo
            Bar
            instanceof Foo
            bool(true)
            bool(true)
            instanceof Bar
            bool(false)
            bool(true)
            subclass of Foo
            bool(false)
            bool(true)
            subclass of Bar
            bool(false)
            bool(false)
            

            【讨论】:

              猜你喜欢
              • 2023-01-24
              • 1970-01-01
              • 2010-11-26
              • 1970-01-01
              • 2018-07-05
              • 2013-11-01
              • 1970-01-01
              • 2011-12-23
              • 2019-02-09
              相关资源
              最近更新 更多