How would I skip optional arguments in a function call?

Viewed 78887

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.

21 Answers

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.

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.

This feature is implemented in PHP 8.0

PHP 8 introduced named arguments

which:

allows skipping default values arbitrarily

The documentation for reference

No changes necessary to use this feature:

lets use OPs function function getData($name, $limit = '50', $page = '1')

Usage

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

Native functions will also use this feature

htmlspecialchars($string, double_encode: false);
// Same as
htmlspecialchars($string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);

Netbeans IDE 12.3 Feature Supported

This feature is supported, with the exception of code completion for named arguments, looks better ;)

enter image description here

This is kind of an old question with a number of technically competent answers, but it cries out for one of the modern design patterns in PHP: Object-Oriented Programming. Instead of injecting a collection of primitive scalar data types, consider using an "injected-object" that contains all of the data needed by the function. http://php.net/manual/en/language.types.intro.php

The injected-object may have property validation routines, etc. If the instantiation and injection of data into the injected-object is unable to pass all of the validation, the code can throw an exception immediately and the application can avoid the awkward process of dealing with potentially incomplete data.

We can type-hint the injected-object to catch mistakes before deployment. Some of the ideas are summarized in this article from a few years ago.

https://www.experts-exchange.com/articles/18409/Using-Named-Parameters-in-PHP-Function-Calls.html

I had to make a Factory with optional parameters, my workaround was to use the null coalescing operator:

public static function make(
    string $first_name = null,
    string $last_name = null,
    string $email = null,
    string $subject = null,
    string $message = null
) {
    $first_name = $first_name ?? 'First';
    $last_name  = $last_name ?? 'Last';
    $email      = $email ?? 'foo@bar.com';
    $subject    = $subject ?? 'Some subject';
    $message    = $message ?? 'Some message';
}

Usage:

$factory1 = Factory::make('First Name Override');
$factory2 = Factory::make(null, 'Last Name Override');
$factory3 = Factory::make(null, null, null, null 'Message Override');

Not the prettiest thing, but might be a good pattern to use in Factories for tests.

As of PHP 8.0.0, declaring mandatory arguments after optional arguments is deprecated.

You can now omit optional parameters.

Example:

<?php

function foo ( $a = '1', $b = '2', $c = '3'  ){
   return "A is " . $a . ", B is " . $b . ", C is " . $b  
}

echo foo(c: '5');  
// Output A is 1, B is 2, C is 5
Related