Does PHP allow named parameters so that optional arguments can be omitted from function calls?

11,709

Solution 1

No, it is not possible (before PHP 8.0): if you want to pass the third parameter, you have to pass the second one. And named parameters are not possible either.


A "solution" would be to use only one parameter, an array, and always pass it... But don't always define everything in it.

For instance :

function foo($params) {
    var_dump($params);
}

And calling it this way : (Key / value array)

foo([
    'a' => 'hello',
]);

foo([
    'a' => 'hello',
    'c' => 'glop',
]);

foo([
    'a' => 'hello',
    'test' => 'another one',
]);

Will get you this output :

array
  'a' => string 'hello' (length=5)

array
  'a' => string 'hello' (length=5)
  'c' => string 'glop' (length=4)

array
  'a' => string 'hello' (length=5)
  'test' => string 'another one' (length=11)

But I don't really like this solution :

  • You will lose the phpdoc
  • Your IDE will not be able to provide any hint anymore... Which is bad

So I'd go with this only in very specific cases -- for functions with lots of optional parameters, for instance...

Solution 2

PHP 8 was released on November 26, 2020 with a new feature called named arguments.

In this major version release, "named parameters" (aka "named arguments") afford developers some really cool new techniques when calling native and custom functions.

The custom function in this question can now be called with the first parameter (because there is no default for it) and then only the third parameter passed by using named parameters like this: (Demo)

function foo($a, $b = '', $c = '') {
    echo $a . '&' . $b . '&' . $c;
}

foo("hello", c: "bar"); 
// output: hello&&bar

Notice that the second parameter did not need to be declared in the function call because it has a default value defined -- the default value is automatically used within the function body.

Part of the beauty of this new feature is that you don't need to be careful about the order of your named parameters -- the order of their declaration is irrelevant. foo(c: "bar", a: "hello"); works just the same. Having the ability to "skip" declarations and write declarative parameters will improve the readability of your scripts. The only downside of this new feature is that there will be a little bit more bloat in the function calls, but I (and many others) think the benefits outweigh this "cost".

Here is an example of a native function omitting the limit parameter, writing the parameters out of their normal order, and declaring a reference variable. (Demo)

echo preg_replace(
         subject: 'Hello 7',
         pattern: '/[a-z ]/',
         count: $counted,
         replacement: ''
     )
     . " & " . $counted;
// output: H7 & 5

There is more to tell about this new feature. You can even use an associative array to pass the named parameters to the function where the spread/splat operator can be used to unpack the data!

(*notice the slight difference in declaring the reference variable.) (Demo)

$params = [
    'subject' => 'Hello 7',  // normally third parameter
    'pattern' => '/[a-z ]/', // normally first parameter
    // 'limit'               // normally fourth parameter, omitted for this demonstration; the default -1 will be used
    'count' => &$counted,    // normally fifth parameter
    //         ^-- don't forget to make it modifiable!
    'replacement' => '',     // normally second parameter
];
echo preg_replace(...$params) . " & " . $counted;
// same output as the previous snippet

For more information, here are a few leads that explain further about this feature and some common related errors: (I have no affiliation with the following sites)

Solution 3

No, PHP cannot pass arguments by name.

If you have a function that takes a lot of arguments and all of them have default values you can consider making the function accept an array of arguments instead:

function test (array $args) {
    $defaults = array('a' => '', 'b' => '', 'c' => '');
    $args = array_merge($defaults, array_intersect_key($args, $defaults));

    list($a, $b, $c) = array_values($args);
    // an alternative to list(): extract($args);

    // you can now use $a, $b, $c       
}

See it in action.

Solution 4

As of PHP 5.4 you have shorthand array syntax (not nessecary to specify arrays with cumbersome "array" and instead use "[]").

You can mimic named parameters in many ways, one good and simple way might be:

bar('one', ['a1' => 'two', 'bar' => 'three', 'foo' => 'four']);
// output: twothreefour

function bar ($a1, $kwargs = ['bar' => null, 'foo' => null]) {
    extract($kwargs);
    echo $a1;
    echo $bar;
    echo $foo;
}

Solution 5

No, it isn't.

The only way you can somewhat do that is by using arrays with named keys and what not.

Share:
11,709
Stefano Borini
Author by

Stefano Borini

Updated on June 17, 2022

Comments

  • Stefano Borini
    Stefano Borini about 2 years

    Is it possible in PHP to specify a named optional parameter when calling a function/method, skipping the ones you don't want to specify (like in python)?

    Something like:

    function foo($a, $b = '', $c = '') {
        // whatever
    }
    
    
    foo("hello", $c="bar"); // we want $b as the default, but specify $c
    
    • Petruza
      Petruza almost 13 years
      Actually in your code sample, the $c="bar" is assigning bar to a $c in the caller scope (not in the called function foo) and then passing the assigned value to foo() as the second parameter, which will be received as the local $b variable.
    • Jsowa
      Jsowa almost 4 years
      Named arguments are available only since PHP 8.0. stackoverflow.com/a/64072408/7082164
  • Adriano Varoli Piazza
    Adriano Varoli Piazza almost 15 years
    The CakePHP -at least- uses this pattern extensively
  • Pascal MARTIN
    Pascal MARTIN almost 15 years
    NULL is not the default -- not always, and not in this case : here, the default would be an empty string ; and no, NULL and an empty string are not "the same" : see operators === and !==, for instance...
  • davethegr8
    davethegr8 almost 15 years
    Oh, I hadn't realized it was NULL instead of empty, since I'm always using '' as the default and then checking to see if(!$value)
  • Petruza
    Petruza almost 13 years
    Sorry for the OT, but do you know any editor that provides code hints for PHP? any for MacOS? thanks!
  • Pascal MARTIN
    Pascal MARTIN almost 13 years
    code hints ? I would say all IDE do (netbeans, Eclipse PDT, PHPStorm, ...) ; no idea about Mac ; but those might work on Mac
  • James Butler
    James Butler about 12 years
    Ermmm, that is not valid php syntax!
  • Nadir Sampaoli
    Nadir Sampaoli about 12 years
    Sorry, it should be fixed now.
  • EFC
    EFC over 11 years
    @Petruza in case you have not found it yet, try Coda for MacOS. Does a nice job of hinting for PHP.
  • binki
    binki over 8 years
    But wouldn’t $bar be undefined if I called bar('one', ['x' => 'blah']);? Even in this scenario, extract() seems dangerous and unnecessary…
  • Joshua
    Joshua about 3 years
    PHP 8.0 now supports named arguments stackoverflow.com/a/19127007/6577664