50

Most of us know the following syntax:

function funcName($param='value'){
    echo $param;
}
funcName();

Result: "value"

We were wondering how to pass default values for the 'not last' paramater? I know this terminology is way off, but a simple example would be:

function funcName($param1='value1',$param2='value2'){
    echo $param1."\n";
    echo $param2."\n";
}

How do we accomplsh the following:

funcName(---default value of param1---,'non default');

Result:

value1
not default

Hope this makes sense, we want to basically assume default values for the paramaters which are not last.

Thanks.

MrCode
  • 63,975
  • 10
  • 90
  • 112
anonymous-one
  • 14,454
  • 18
  • 60
  • 84
  • I really dont understand your question / problem .. [your second example works fine](http://codepad.org/DdmSdFEY) – Manse May 15 '12 at 08:47
  • The issue is not that function – Nanne May 15 '12 at 08:54
  • 1
    I apologize for being unclear. But frankly, I dont know how to term 'assume the default value for a parameter which is NOT the last in the list of parameters'. – anonymous-one May 15 '12 at 09:04
  • 1
    Does my suggestion of specifying a `null` default value not provide a solution? Am just wondering why someone objected enough to mark it down without commenting why – Brad May 15 '12 at 09:29
  • I don't get why you want to do this. If you have control over the function parameters, why not sort it the right way. For me a Parameter which has a default Value is less important than the Parameters which doesn't. – Christoph Winkler May 15 '12 at 09:46

4 Answers4

59

PHP doesn't support what you're trying to do. The usual solution to this problem is to pass an array of arguments:

function funcName($params = array())
{
    $defaults = array( // the defaults will be overidden if set in $params
        'value1' => '1',
        'value2' => '2',
    );

    $params = array_merge($defaults, $params);

    echo $params['value1'] . ', ' . $params['value2'];
}

Example Usage:

funcName(array('value1' => 'one'));                    // outputs: one, 2
funcName(array('value2' => 'two'));                    // outputs: 1, two
funcName(array('value1' => '1st', 'value2' => '2nd')); // outputs: 1st, 2nd
funcName();                                            // outputs: 1, 2

Using this, all arguments are optional. By passing an array of arguments, anything that is in the array will override the defaults. This is possible through the use of array_merge() which merges two arrays, overriding the first array with any duplicate elements in the second array.

MrCode
  • 63,975
  • 10
  • 90
  • 112
  • 2
    This seams like the cleanest way of doing things. Although slightly bloated (not your fault... phps, for not having this available)... – anonymous-one May 15 '12 at 09:05
  • 1
    Named arguments are available since PHP 8.0: https://stackoverflow.com/a/64072408/7082164 – Jsowa Sep 25 '20 at 23:50
13

Unfortunately, this is not possible. To get around this, I would suggest adding the following line to your function:

$param1 = (is_null ($param1) ? 'value1' : $param1);

You can then call it like this:

funcName (null, 'non default');

Result:

value1
non default
Jeroen
  • 13,056
  • 4
  • 42
  • 63
  • 3
    are the outer parentheses adding some benefit? It looks like it would work just as well with `$param1 = is_null ($param1) ? 'value1' : $param1;` – Anthony Feb 14 '14 at 15:50
  • I use parentheses for clarity for the coder. Debugging is a costly affair, just ask your customers ;) – Herbert Van-Vliet Mar 22 '19 at 10:03
5

PHP 8.0 update

Solution you want is available since PHP 8.0: named arguments

function funcName($param1 = 'value1', $param2 = 'value2', $param3 = 'value3') {
    ...
}

Previously you had to pass some value as $param1, either null or default value, but now you can only pass a second parameter.

funcName(param2: 'value');

And you don't need to care about argument order.

funcName(param2: 'value', param3: 'value');

//is the same as

funcName(param3: 'value', param2: 'value');

Moreover there are some fancy things we can do with named arguments, like passing an array as arguments. It's helpful when we don't know which exact keys we store in an array and we don't need to worry about the order of variables anymore.

$args = [
    'param3' => 'value',
    'param2' => 'value',
];

funcName(...$args);

//works the same as

funcName(param2: 'value', param3: 'value');

We even don't need to name our values in an array as arguments (of course until we match order of arguments).

$args = [
    'value1',
    'param3' => 'value3',
    'param2' => 'value2',
];

funcName(...$args);

//works the same as

funcName(param1: 'value1', param3: 'value3', param2: 'value2');

//and

funcName('value1', 'value2', 'value3');
Jsowa
  • 9,104
  • 5
  • 56
  • 60
1

The Simple solution of your problem is, instead of using:

funcName(---default value of param1---,'non default');

Use the following Syntax:

funcName('non default',---default value of param1---);

Example:

function setHeight2($maxheight,$minheight = 50) {
    echo "The MAX height is : $maxheight <br>";
    echo "The MIN height is : $minheight <br>";
}

setHeight2(350,250);
setHeight2(350); // will use the default value of 50
Bas Peeters
  • 3,269
  • 4
  • 33
  • 49
Rohit Pavaskar
  • 308
  • 2
  • 12