Reputation: 2310
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
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
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
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
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
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
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
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
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
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
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