Is it possible to use named function parameters in PHP?

17,293

Solution 1

PHP 8.0 added support for named arguments with the acceptance of an RFC.

Named arguments are passed by prefixing the value with the parameter name followed by a colon. Using reserved keywords as parameter names is allowed. The parameter name must be an identifier, specifying dynamically is not allowed.

E.g. to pass just the 3rd optional parameter in your example:

foo(timeout: 3);

Prior to PHP 8 named parameters were not possible in PHP. Technically when you call foo($timeout=3) it is evaluating $timeout=3 first, with a result of 3 and passing that as the first parameter to foo(). And PHP enforces parameter order, so the comparable call would need to be foo("", "", $timeout=3). You have two other options:

  • Have your function take an array as parameter and check the array keys. I personally find this ugly but it works and is readable. Upside is simplicity and it's easy to add new parameters later. Downside is your function is less self-documenting and you won't get much help from IDEs (autocomplete, quick function param lookups, etc.).
  • Set up the function with no parameters and ask PHP for the arguments using func_get_args() or use the ... variable length arguments feature in PHP 5.6+. Based on the number of parameters you can then decide how to treat each. A lot of JQuery functions do something like this. This is easy but can be confusing for those calling your functions because it's also not self-documenting. And your arguments are still not named.

Solution 2

Old question, but here is some more information.

As stated in the other answers, PHP does not directly support named parameters. VBA is another language which has that luxury.

In PHP, you can use a fairly reasonable substitute. PHP’s array handling is particularly good, and you can use an associative array to pass an array of parameters, as follows:

function foo($parms=[]) {
    $username = $parms['username'] ?? '…';
    $password = $parms['password'] ?? '…';
    $timeout  = $parms['timeout'] ?? '…';
}

foo(['timeout'=>10]);

Note the use of the ?? operator to allow a simple default if the input array element doesn’t exist. Before PHP 7, you would use ?: which is subtly different, but gives the same result in this case. Thanks to @LeeGee for picking this up.

Not as slick, but named parameters have another important role: they allow you to work with a large number of options without an excessively long list of ordered parameters.

An alternative way of writing the function is to use the `extract function:

function foo($parms=[]) {
    $username = '…';
    $password = '…';
    $timeout = '…';
    extract($parms,EXTR_IF_EXISTS);
}

Here the extract function copies the values into the variables, but only if they have already been defined. This prevents importing variables you didn’t know about.

Solution 3

Named Arguments are not supported in PHP 7.* or lower.

BUT, it's probably coming to PHP 8 https://wiki.php.net/rfc/named_params

Let's see how it ends the voting phase! :D

UPDATED: The RFC was approved. Named Arguments will be implemented in PHP 8.

Solution 4

Updated answer for 2020: PHP 8 will support named arguments, the RFC passed.

What does this mean?

Both native functions and your current code will be able to use named parameters.

How does it work?

Let's say you have a function defined:

function foo($a = 10, $b = 20, $c = 30) {
    return $a * $b - $c;
}

you will now be able to call this function like so:

foo(a: 30, c: 10, b: 5);
foo(5, c: 60, b: 10);
foo(c: 30, b: 20, a: 10);
Share:
17,293
Justin
Author by

Justin

Updated on June 05, 2022

Comments

  • Justin
    Justin about 2 years

    Is it possible in php like in python to have named function parameters? An example use case is:

    function foo($username = "", $password = "", $timeout = 10) {
    
    }
    

    I want to override $timeout:

    foo("", "", 3);
    

    Ugly. I would much rather do:

    foo(timeout=3);
    
  • Fluffeh
    Fluffeh over 10 years
    I think it is a general question he is asking about it, not in this one particular case.
  • Justin
    Justin over 10 years
    Timeout does not belong first though, just very strange behavior, the standard is username, password.
  • Axel
    Axel over 10 years
    so if you want to you original order - than you'll have to use func_get_args - count them, and then set them to the variables that you need, in other cases - how would php know that the timeout you are passing - isn't the username ?
  • Justin
    Justin over 10 years
    How python does it: foo(timeout=3). Ok, guess I have to use dirty func_get_args().
  • Admin
    Admin over 9 years
    Hurray for the assignment technique from an esthetics pov. There is just one drawback, it looks alot like named parameters (ahem, that's the point no?). But that might give the impression that order doesn't matter anymore, where in fact it does. I suppose that part of it is not so self documenting. So to correct your answer, technically you can only do: foo( '', '', $timeout = 3 );
  • Admin
    Admin over 9 years
    ps: there are some other minor downsides: performance (rarely will be an issue) and potentially overwriting existing variables. All in all the advantage over foo( '', '', 3 /*timeout*/ ); is questionable.
  • Jacob Thomason
    Jacob Thomason almost 4 years
    You should probably update this for PHP8. Named arguments are supported.
  • Matt S
    Matt S over 3 years
    @JacobThomason Updated, thanks. I'll update it again after PHP8 is released.
  • Kamlesh
    Kamlesh about 3 years
    NOT WORKED FOR ME. THANKS. // public function getPaginatedRecords($queryObject = '', $currentPage = 1, $limit = 10){}. // $this->getPaginatedRecords(queryObject: $user_data, currentPage: 1, limit: 10);
  • Joe Boris
    Joe Boris over 2 years
    FYI, unpacking an associative array with ... (i.e. foo(...["timeout"=>3])) is an option too. It might have been available before 8.0 but I'm not sure. Idk if it's worth mentioning