Any way to specify optional parameter values in PHP?

后端 未结 12 882
谎友^
谎友^ 2020-11-28 06:54

Let\'s say I\'ve got a PHP function foo:

function foo($firstName = \'john\', $lastName = \'doe\') {
    echo $firstName . \" \" . $lastName;
}
// foo(); --&g         


        
相关标签:
12条回答
  • 2020-11-28 07:09

    A variation on the array technique that allows for easier setting of default values:

    function foo($arguments) {
      $defaults = array(
        'firstName' => 'john',
        'lastName' => 'doe',
      );
    
      $arguments = array_merge($defaults, $arguments);
    
      echo $arguments['firstName'] . ' ' . $arguments['lastName'];
    }
    

    Usage:

    foo(array('lastName' => 'smith')); // output: john smith
    
    0 讨论(0)
  • 2020-11-28 07:12

    The way you want: no.

    You could use some special mark, like NULL to note that value is not supplied:

    function foo($firstName, $lastName = 'doe') {
        if (is_null($firstName))
            $firstName = 'john';
        echo $firstName . " " . $lastName;
    }
    
    foo(null, 'smith');
    
    0 讨论(0)
  • 2020-11-28 07:15

    PHP does not support named parameters for functions per se. However, there are some ways to get around this:

    1. Use an array as the only argument for the function. Then you can pull values from the array. This allows for using named arguments in the array.
    2. If you want to allow optional number of arguments depending on context, then you can use func_num_args and func_get_args rather than specifying the valid parameters in the function definition. Then based on number of arguments, string lengths, etc you can determine what to do.
    3. Pass a null value to any argument you don't want to specify. Not really getting around it, but it works.
    4. If you're working in an object context, then you can use the magic method __call() to handle these types of requests so that you can route to private methods based on what arguments have been passed.
    0 讨论(0)
  • 2020-11-28 07:18

    Sadly what you're trying to do has no "syntactic sugar" way of doing it. They're all varying forms of WTF.

    If you need a function that takes an undefined number of arbitrary parameters,

    function foo () { 
         $args = func_get_args(); 
         # $args = arguments in order 
    }
    

    Will do the trick. Try avoid using it too much, because for Php this is a bit on the magical side.

    You could then optionally apply defaults and do strange things based on parameter count.

    function foo(){ 
       $args = func_get_args();
       if( count($args) < 1 ){ 
           return "John Smith"; 
       }
       if( count($args) < 2 ) { 
           return "John " .$args[0];
       }
       return $args[0] . " " . $args[1];
    }
    

    Also, you could optionally emulate Perl style parameters,

    function params_collect( $arglist ){ 
        $config = array();
        for( $i = 0; $i < count($arglist); $i+=2 ){ 
           $config[$i] = $config[$i+1];
        }
        return $config; 
    }
    function param_default( $config, $param, $default ){ 
        if( !isset( $config[$param] ) ){ 
               $config[$param] = $default;
        }
        return $config;
    }
    
    function foo(){ 
       $args = func_get_args();
       $config = params_collect( $args ); 
       $config = param_default( $config, 'firstname' , 'John' ); 
       $config = param_default( $config, 'lastname' ,  'Smith' ); 
       return $config['firstname'] . '  ' . $config['lastname'];   
    }
    
    foo( 'firstname' , 'john', 'lastname' , 'bob' ); 
    foo( 'lastname' , 'bob', 'firstname', 'bob' ); 
    foo( 'firstname' , 'smith'); 
    foo( 'lastname', 'john' );
    

    Of course, it would be easier to use an array argument here, but you're permitted to have choice ( even bad ways ) of doing things.

    notedly, this is nicer in Perl because you can do just foo( firstname => 'john' );

    • func_get_args at php.net
    0 讨论(0)
  • 2020-11-28 07:19

    There are a few 'options' style implementations mentioned here. None thus far are very bulletproof if you plan to use them as as standard. Try this pattern:

    function some_func($required_parameter, &$optional_reference_parameter = null, $options = null) {
        $options_default = array(
            'foo' => null,
        );
        extract($options ? array_intersect_key($options, $options_default) + $options_default : $options_default);
        unset($options, $options_default);
    
        //do stuff like
        if ($foo !== null) {
            bar();
        }
    }
    

    This gives you function-local variables (just $foo in this example) and prevents creating any variables that do not have a default. This is so no one can accidentally overwrite other parameters or other variables within the function.

    0 讨论(0)
  • 2020-11-28 07:20

    I wish this solution had been on SO when I started using PHP 2.5 years ago. It works great in the examples I have created, and I don't see why it shouldn't be thoroughly extensible. It offers the following benefits over those proposed previously:

    (i) all access to parameters within the function is by named variables, as if the parameters were fully declared, rather than requiring array access

    (ii) it is very quick and easy to adapt existing functions

    (iii) only a single line of additional code is required for any function (in addition to the inescapable necessity of defining your default parameters, which you would be doing in the function signature anyway, but instead you define them in an array). Credit for the additional line is wholly due to Bill Karwin. This line is identical for every function.

    Method

    Define your function with its mandatory parameters, and an optional array

    Declare your optional parameters as local variables

    The crux: replace the pre-declared default value of any optional parameters using those you have passed via the array.

    extract(array_merge($arrDefaults, array_intersect_key($arrOptionalParams, $arrDefaults)));
    

    Call the function, passing its mandatory parameters, and only those optional parameters that you require

    For example,

    function test_params($a, $b, $arrOptionalParams = array()) {
    
    $arrDefaults = array('c' => 'sat',
    
                         'd' => 'mat');
    
    extract(array_merge($arrDefaults, array_intersect_key($arrOptionalParams, $arrDefaults)));
    
    echo "$a $b $c on the $d";
    
    }
    

    and then call it like this

    test_params('The', 'dog', array('c' => 'stood', 'd' => 'donkey'));
    test_params('The', 'cat', array('d' => 'donkey'));
    test_params('A', 'dog', array('c' => 'stood'));
    

    Results:

    The dog stood on the donkey

    The cat sat on the donkey

    A dog stood on the mat

    0 讨论(0)
提交回复
热议问题