Desmond Liang
Desmond Liang

Reputation: 2310

can php function parameters be passed in different order as defined in declaration

Suppose I have a function/method F() that takes 3 parameters $A, $B and $C defined as this.

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

Suppose I don't want to follow the order to pass the parameters, instead can I make a call like this?

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

instead of

F(1,2,3)

Upvotes: 15

Views: 9544

Answers (10)

k0pernikus
k0pernikus

Reputation: 66679

Starting with php@8, php will suppport named arguments.

This will allow passing arguments in a different order as long as you provide their name when calling.

E.g. this may look like:

<?php

class SomeDto
{
    public function __construct(
        public int $foo = 13,
        public string $bar = 'bar',
        public string $baz = 'baz',
    ) {}
}

$example = new SomeDto(bar: 'fnord!');

var_dump($example);

And the result will be:

object(SomeDto)#1 (3) {
  ["foo"]=> int(13)
  ["bar"]=> string(6) "fnord!"
  ["baz"]=> string(3) "baz"
}

Upvotes: 4

Samuel Cook
Samuel Cook

Reputation: 16828

PHP 8.0 introduced named arguments. This means that you can now pass function arguments in any order. Here are a few examples:

function F($A,$B,$C){
    echo sprintf( 'A: %s, B: %s, C: %s %s', $A, $B, $C, PHP_EOL );
}

#using all positional arguments
F(1,2,3);

#using all named arguments
F(B:2,C:3,A:1);

#using a mix of positional and named arguments
F(1,C:3,B:2);

There are a number of instances where errors can occur. This mainly occurs when overwriting previous values. For instance, when using a mix of positional and named: F(1, A:2, C:3); or redefining the named argument: F(A:1, A:2).

Upvotes: 1

B.Turner
B.Turner

Reputation: 11

Another method might be helpful for some is to pass a single argument as a string with 'key words', like...

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

Then your parameters can be in any order, can be missing all together, and the letter case is insignificant. You can decide up-front how to encode passed values: DETAILS=6 or DETAILS(6) or anything else.

So, foo("NAKED DETAILS(6)") would work, or foo("DETAILS(6) NAKED") would work. It can also be made to work with something like this...

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

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

It does require the code to parse-out the values

I find this most effective when passing (and detecting the presence of) key words (like 'NAKED' above)

Upvotes: 1

Tolga Ulas
Tolga Ulas

Reputation: 1

from php site:

In PHP 5.6 and later, argument lists may include the ... token to denote that the function accepts a variable number of arguments. The arguments will be passed into the given variable as an array; for example:

<?php
function sum(...$numbers) {
    $acc = 0;
    foreach ($numbers as $n) {
        $acc += $n;
    }
    return $acc;
}

echo sum(1, 2, 3, 4);
?>

Accompanied with post-process by instanceof or is_subclass_of as in here(below):

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)

Upvotes: 0

Jacob Relkin
Jacob Relkin

Reputation: 163268

Absolutely not.

One way you'd be able to pass in unordered arguments is to take in an associative array:

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

You could then invoke it like this:

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

Upvotes: 13

Leniel Maccaferri
Leniel Maccaferri

Reputation: 102428

Taken from here...

If you prefer to use named arguments to your functions (so you don't have to worry about the order of variable argument lists), you can do so PERL style with anonymous arrays:

<?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"));
?>

will output:

named_arg1 : arg1_value
named_arg2 : arg2_value

Upvotes: 0

moinudin
moinudin

Reputation: 138387

PHP doesn't have named arguments, so the short answer is no. There are two solutions I can find, although neither are all that fantastic.

You could define your function to take its arguments as an array, like 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'));

That method unfortunately requires that you modify your function, and as a result I don't like it. The other option is to use this wrapper class which lets you use named arguments in one of the following ways:

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

Upvotes: 1

keithjgrant
keithjgrant

Reputation: 12749

No, you can't. Something I've done for functions where many parameters are optional or I don't want order to matter is to instead use a single array parameter.

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

Upvotes: -1

Demian Brecht
Demian Brecht

Reputation: 21368

No, but you could pass in an associative array to handle this:

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

and then access it by:

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

Upvotes: 1

Cray
Cray

Reputation: 2454

No, not using the standrad php syntax.

There are always tricks for that of course, like if you are defining the function yourself, you could do something like

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

But for that you would have to rewrite the original function of course, so that it would accept an array as arguments, as opposed to just accepting the arguments themselves.

Upvotes: -1

Related Questions