rfc:skipparams

This is an old revision of the document!


Skipping optional parameters for functions

Introduction

As PHP does not have named parameter support, a very common for function is to have many optional arguments, like this:

   function create_query($where, $order_by, $join_type='', $execute = false, $report_errors = true)
   {...}

If we always use defaults, it's fine. But what if we need ot change $report_errors but don't care about the others? We'd have to find function definition and copy-paste all other defaults into the call, which is annoying, error-prone and may not do what you wanted if some of the defaults change.

Proposal

The proposal is to allow skipping optional arguments in a call, thus making them assume default values as they do when they are not provided, like this:

    create_query("deleted=0", "name", default, default, /*report_errors*/ true);

This means that $join_type and $execute are going to use defaults. Of course, if we ever get implementation of named parameters, it may also solve this problem, but until we do, this can be a partial solution.

Only optional parameters can be skipped this way, skipping non-optional one will produce the same error it does now when function is not given engough parameters.

Implementation

On the engine level, it will be implemented by putting NULL in the place where the parameter is passed. Functions dealing with argument handling will be updated.

See example implementation above. Tests for most use cases will be added shortly.

User functions

User functions would have defaults for optional args take place of skipped arguments, just as before.

Internal functions

For internal functions, parameter parser will ignore the NULLs, thus leaving the defaults supplied by the caller intact. Again, skipping non-optional parameter is an error.

Variadic functions will not return skipped parameters in argc and argv, effectively ignoring them, so:

     var_dump(2,default,1);

is the same as:

     var_dump(2,1);

func_get_args()

func_get_args() will skip parameters that are not supplied, so it would provide just the parameters that are actually supplied to the function. Thus, this code:

   function test($a=1, $b=2, $c=3) {
      var_dump(func_get_args());
   }
   test(1,default,4);

will produce:

    array(2) {
      [0]=>
      int(1)
      [2]=>
      int(4)
    }

This means that if you are looping over func_get_args() result, you should use foreach() and not counter-based for(). func_num_args() will also ignore skipped parameters and give only the number of parameters actually passed. func_get_arg() will return false for parameter that was not passed.

call_user_func_array()

call_user_func_array() will allow skipping arguments too by skipping them in supplied arguments array, like this:

    call_user_func_array('test', array(42, 2=>43, 4=>44));

call_user_func will allow argument skipping directly:

    call_user_func('test', 42, default, 44);

with the same result.

User request examples

Issues raised

  • Support for internal functions doing manual ZEND_NUM_ARGS()

Changelog

  • 2012-04-13 First draft.
  • 2012-07-07 Changed empty parameter to use 'default'
rfc/skipparams.1341732387.txt.gz · Last modified: 2017/09/22 13:28 (external edit)