views:

270

answers:

4

Is it possible in PHP 4/5 to specify a named optional parameter when calling, 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

Thanks

+4  A: 

With PHP, the order of arguments is what matters. You can't specify a particular argument out of place, but instead, you can skip arguments by passing a NULL, as long as you don't mind the value in your function having a NULL value.

foo("hello", NULL, "bar");
davethegr8
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...
Pascal MARTIN
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)
davethegr8
+3  A: 

No, it is not possible : 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 :

foo(array(
    'a' => 'hello',
));

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

foo(array(
    '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 optionnal parameters, for instance...

Pascal MARTIN
+2  A: 

No, it isn't.

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

Alix Axel
The CakePHP -at least- uses this pattern extensively
Adriano Varoli Piazza
A: 

It's not exactly pretty, but it does the trick, some might say.

class NamedArguments {

    static function init($args) {
        $assoc = reset($args);
        if (is_array($assoc)) {
            $diff = array_diff(array_keys($assoc), array_keys($args));
            if (empty($diff)) return $assoc;
            trigger_error('Invalid parameters: '.join(',',$diff), E_USER_ERROR);
        }
        return array();
    }

}

class Test {

    public static function foobar($required, $optional1 = '', $optional2 = '') {
        extract(NamedArguments::init(get_defined_vars()));
        printf("required: %s, optional1: %s, optional2: %s\n", $required, $optional1, $optional2);
    }

}

Test::foobar("required", "optional1", "optional2");
Test::foobar(array(
    'required' => 'required', 
    'optional1' => 'optional1', 
    'optional2' => 'optional2'
    ));
David