How would I skip optional arguments in a function call?

76,430

Solution 1

Your post is correct.

Unfortunately, if you need to use an optional parameter at the very end of the parameter list, you have to specify everything up until that last parameter. Generally if you want to mix-and-match, you give them default values of '' or null, and don't use them inside the function if they are that default value.

Solution 2

Nope, it's not possible to skip arguments this way. You can omit passing arguments only if they are at the end of the parameter list.

There was an official proposal for this: https://wiki.php.net/rfc/skipparams, which got declined. The proposal page links to other SO questions on this topic.

Solution 3

There's no way to "skip" an argument other than to specify a default like false or null.

Since PHP lacks some syntactic sugar when it comes to this, you will often see something like this:

checkbox_field(array(
    'name' => 'some name',
    ....
));

Which, as eloquently said in the comments, is using arrays to emulate named arguments.

This gives ultimate flexibility but may not be needed in some cases. At the very least you can move whatever you think is not expected most of the time to the end of the argument list.

Solution 4

Nothing has changed regarding being able to skip optional arguments, however for correct syntax and to be able to specify NULL for arguments that I want to skip, here's how I'd do it:

define('DEFAULT_DATA_LIMIT', '50');
define('DEFAULT_DATA_PAGE', '1');

/**
 * getData
 * get a page of data 
 *
 * Parameters:
 *     name - (required) the name of data to obtain
 *     limit - (optional) send NULL to get the default limit: 50
 *     page - (optional) send NULL to get the default page: 1
 * Returns:
 *     a page of data as an array
 */

function getData($name, $limit = NULL, $page = NULL) {
    $limit = ($limit===NULL) ? DEFAULT_DATA_LIMIT : $limit;
    $page = ($page===NULL) ? DEFAULT_DATA_PAGE : $page;
    ...
}

This can the be called thusly: getData('some name',NULL,'23'); and anyone calling the function in future need not remember the defaults every time or the constant declared for them.

Solution 5

The simple answer is No. But why skip when re-arranging the arguments achieves this?

Yours is an "Incorrect usage of default function arguments" and will not work as you expect it to.

A side note from the PHP documentation:

When using default arguments, any defaults should be on the right side of any non-default arguments; otherwise, things will not work as expected.

Consider the following:

function getData($name, $limit = '50', $page = '1') {
    return "Select * FROM books WHERE name = $name AND page = $page limit $limit";
}

echo getData('some name', '', '23');   // won't work as expected

The output will be:

"Select * FROM books WHERE name = some name AND page = 23 limit"

The Correct usage of default function arguments should be like this:

function getData($name, $page = '1', $limit = '50') {
    return "Select * FROM books WHERE name = $name AND page = $page limit $limit";
}

echo getData('some name', '23');  // works as expected

The output will be:

"Select * FROM books WHERE name = some name AND page = 23 limit 50"

Putting the default on your right after the non-defaults makes sure that it will always retun the default value for that variable if its not defined/given Here is a link for reference and where those examples came from.

Edit: Setting it to null as others are suggesting might work and is another alternative, but may not suite what you want. It will always set the default to null if it isn't defined.

Share:
76,430

Related videos on Youtube

Chuck Le Butt
Author by

Chuck Le Butt

Hello.

Updated on November 01, 2021

Comments

  • Chuck Le Butt
    Chuck Le Butt over 2 years

    OK I totally forgot how to skip arguments in PHP.

    Lets say I have:

    function getData($name, $limit = '50', $page = '1') {
        ...
    }
    

    How would I call this function so that the middle parameter takes the default value (ie. '50')?

    getData('some name', '', '23');
    

    Would the above be correct? I can't seem to get this to work.

    • Rizier123
      Rizier123 almost 9 years
      @Chuck for what are you looking for exactly? Like a workaround or a class to implement this or ... ?
    • Chuck Le Butt
      Chuck Le Butt almost 9 years
      @Rizier123 I'm asking to see if the current version of PHP supports skipping arguments (like other languages do). The current answers may be outdated. From the bounty description: "Current answers are five years old. Does the current version of PHP change things?"
    • Rizier123
      Rizier123 almost 9 years
      @Chuck Then the answer will probably be: that nothing changed; without a workaround/code you won't get your functionality.
    • Snapey
      Snapey about 7 years
      All the answers here seem to assume you have control over the function being called. If that function is part of a library or framework you have no option but to specify something for argument 2 if you need argument 3. The only option is to look in the source for the function and replicate the default value.
    • David
      David over 5 years
      It's not possible to skip it, but you can pass the default argument using ReflectionFunction. I posted that answer in a similar question.
    • David
      David over 5 years
  • chaos
    chaos almost 15 years
    I would identify the 'something like this' as 'using arrays to emulate named arguments', FWIW. :)
  • Felix Kling
    Felix Kling over 14 years
    Despite being more flexible you have to remember the parameters you should/can set (as they are not in the signature). So in the end it might be not as useful as it seems but of course this depends on the context.
  • Adam Grant
    Adam Grant almost 12 years
    So what would be the best practices for such a scenario?
  • i am me
    i am me over 8 years
    Can you provide an example?
  • i am me
    i am me over 8 years
    Then how do PHP functions have optional of more/less parameters?
  • Cristik
    Cristik over 8 years
    PHP has support for default parameter values. But those parameters must to be at the end of the list.
  • Cristik
    Cristik over 8 years
    You can find examples in the PHP documentation
  • showdev
    showdev over 8 years
    Nice. But a little explanation would be helpful.
  • EchoSin
    EchoSin about 8 years
    Good answer, but if you want to ommit optional parameter do it this way: function getData($name, $args = array()) { $defaults = array('limit':=>50,'page'=>2); $args=array_merge($defaults,$args); } Now it is possible to call this function with only first parameter like this: getData('foo');
  • Ibrahim Lawal
    Ibrahim Lawal almost 8 years
    You simply duplicated the response. Rather you could have upvoted or commented on it.
  • Lee Saxon
    Lee Saxon over 7 years
    Jerks. Makes me so mad. If you don't like a feature someone else requests, just don't use it. The internet is the worst sometimes.
  • Frank Forte
    Frank Forte about 6 years
    I'm not sure why you have down votes, other than the $c also needing a default value (you cannot have any required arguments after an optional argument).
  • Kamafeather
    Kamafeather over 5 years
    @iamme do $limit = is_numeric($limit) ? $limit : '50'; at the beginning of getData function
  • roelleor
    roelleor almost 5 years
    You'd probably want strict comparison ($limit===null)
  • Christian
    Christian almost 5 years
    This is the best answer since it provides clearly illustrated syntactical explanations! Thank you!
  • Mark Walsh
    Mark Walsh over 4 years
    @LeeSaxon the issue is readability and portability. 1) If someone decides to skip parameters, and someone debugging code misses this fact, great confusion occurs. 2) new code could not work on older versions without a major over haul and chances of mistakes would be very high.
  • xdevs23
    xdevs23 over 3 years
    Perhaps doing it the way it is solved in Kotlin would be the best. You simply specify the name like this getData(name = "some name", page = "23"). Sadly that's not the case