Any way to specify additional parameter values ​​in PHP?

Say I have a PHP function foo:

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

Is it possible to specify only the second optional parameter?

Example:

 foo($lastName='smith'); // output: john smith 
+20
function php optional-parameters
Mar 27 '09 at 17:00
source share
12 answers

PHP does not support named parameters for the functions themselves. However, there are several ways around this:

  • Use an array as the only argument to the function. Then you can infer the values ​​from the array. This allows you to use named arguments in an array.
  • If you want to allow an additional number of arguments depending on the context, then you can use func_num_args and func_get_args instead of specifying valid parameters in the function definition. Then, based on the number of arguments, string lengths, etc., you can determine what to do.
  • Pass a null value to any argument that you do not want to specify. Not really getting around this, but it works.
  • If you work in the context of an object, you can use the magic __call () method to handle these types of requests so that you can route to private methods based on which arguments were passed.
+32
Mar 27 '09 at 17:08
source share

A variant of the array method that makes it easy to set default values:

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

Using:

 foo(array('lastName' => 'smith')); // output: john smith 
+21
Mar 27 '09 at 17:29
source share

You can change your code a bit:

 function foo($firstName = NULL, $lastName = NULL) { if (is_null($firstName)) { $firstName = 'john'; } if (is_null($lastName )) { $lastName = 'doe'; } echo $firstName . " " . $lastName; } foo(); // john doe foo('bill'); // bill doe foo(NULL,'smith'); // john smith foo('bill','smith'); // bill smith 
+9
Mar 27 '09 at 17:48
source share

If you have several optional parameters, one solution should pass a single parameter, which is a hash array:

 function foo(array $params = array()) { echo $params['firstName'] . " " . $params['lastName']; } foo(array('lastName'=>'smith')); 

Of course, in this solution there is no confirmation that the hash field is present or correctly spelled. All you need to check.

+6
Mar 27 '09 at 17:09
source share

No. The usual way to do this is with some heuristics to determine which parameter is implied, such as line length, text input, etc.

Generally speaking, you have to write a function to accept the parameters in the order required for the least required.

+3
Mar 27 '09 at 17:02
source share

As you want: no.

You can use some special label, for example NULL, to note that this value is not specified:

 function foo($firstName, $lastName = 'doe') { if (is_null($firstName)) $firstName = 'john'; echo $firstName . " " . $lastName; } foo(null, 'smith'); 
+3
Mar 27 '09 at 17:08
source share

There are several style implementations of the options mentioned here. So far, they are not bulletproof if you plan to use them as standard ones. Try this template:

 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 functionally local variables (just $foo in this example) and prevents the creation of any variables that don't have a default value. Thus, no one can accidentally overwrite other parameters or other variables inside the function.

+1
Apr 11 '14 at 6:34
source share

I want this solution to be on SO when I started using PHP 2.5 years ago. It works great in the examples I created, and I don't understand why it should not be fully extensible. It offers the following advantages over those previously offered:

(i) all access to the parameters inside the function is carried out using named variables, as if the parameters were fully declared, and did not require access to the array

(ii) adapt existing functions very quickly and easily

(iii) for any function, only one line of additional code is required (in addition to the inevitable need to define your default parameters, which you will do in the function signature in any case, but instead you define them in an array). The credit for the additional line is fully connected with Bill Carvin. This line is identical for each function.

Method

Define your function with its required parameters and optional array

Declare your optional parameters as local variables

The crux: replace the previously declared default value of any optional parameters using the ones you passed through the array.

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

Call a function, pass its required parameters, and only those additional parameters that you need

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 a donkey

Cat sitting on a donkey

There was a dog on the rug

+1
Aug 19 '15 at 14:54
source share

Arguments must be passed in order by position; you cannot skip a parameter as such; you will need to specify a default parameter value to skip it. Perhaps this defeats the goal of what you are trying to achieve.

Without overwriting your function, in order to accept parameters in different ways, here you can use the time invocation method:

 $func = 'foo'; $args = ['lastName' => 'Smith']; $ref = new ReflectionFunction($func); $ref->invokeArgs(array_map(function (ReflectionParameter $param) use ($args) { if (array_key_exists($param->getName(), $args)) { return $args[$param->getName()]; } if ($param->isOptional()) { return $param->getDefaultValue(); } throw new InvalidArgumentException("{$param->getName()} is not optional"); }, $ref->getParameters())); 

In other words, you use reflection to check function parameters and match them to available parameters by name, skipping optional parameters with their default value. Yes, it is ugly and bulky. You can use this sample to create a function such as:

 call_func_with_args_by_name('foo', ['lastName' => 'Smith']); 
+1
Aug 26 '15 at 9:11
source share

If this is used very often, just define a new specialized function:

 function person($firstName = 'john', $lastName = 'doe') { return $firstName . " " . $lastName; } function usualFirtNamedPerson($lastName = 'doe') { return person('john', $lastName); } print(usualFirtNamedPerson('smith')); --> john smith 

Note that you can also change the default value of $ lastname in this process.

When a new function is evaluated differently, just call the function with all parameters. If you want to make this clearer, you can teach your literals in the fin variable or use comments.

 $firstName = 'Zeno'; $lastName = 'of Elea'; print(person($firstName, $lastName)); print(person(/* $firstName = */ 'Bertrand', /* $lastName = */ 'Russel')); 

Well, this is not as short and elegant as person($lastName='Lennon') , but it looks like you cannot have it in PHP. And this is not the sexiest way to encode it, with a super-metaprogramming trick, etc., But what solution would you rather meet in the service process?

0
Nov 15 '16 at 9:33
source share

No, no, but you can use an array:

 function foo ($nameArray) { // Work out which values are missing? echo $nameArray['firstName'] . " " . $nameArray['lastName']; } foo(array('lastName'=>'smith')); 
-one
Mar 27 '09 at 17:09
source share

Unfortunately, what you are trying to do does not have “syntactic sugar”. They are all different forms of WTF.

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

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

Will do the trick. Try not to use it too much, because for Php it is a bit on the magic side.

Then you can optionally apply defaults and do strange things based on the number of parameters.

 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]; } 

In addition, you can further emulate Perl-style options,

 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 are allowed to have a choice (even bad ways) to do something.

note that this is better in Perl, because you can only do foo (firstname => 'john'); Sub>

-one
Mar 27 '09 at 17:11
source share



All Articles