2009-02-23 14 views
7

tengo esto:¿Es posible omitir los parámetros que tienen valores predeterminados en una llamada de función php (5)?

function foo($a='apple', $b='brown', $c='Capulet') { 
    // do something 
} 

es algo como esto sea posible:

foo('aardvark', <use the default, please>, 'Montague'); 
+1

Hay una propuesta para implementar esta característica en php5.5 [https://wiki.php.net/rfc/skipparams](https://wiki.php.net/rfc/skipparams) – Shahid

+0

¿Qué pasa con Syntactic? https://github.com/topclaudy/php-syntactic – cjdaniel

Respuesta

1

Has encontrado la respuesta, pero el enfoque académico/de alto nivel es function currying, que sinceramente nunca he encontrado un buen uso, pero es útil saber que existe.

+0

No creo que currying pueda hacer nada con respecto a los valores predeterminados de los argumentos; son conceptos bastante mutuamente excluyentes. – jpalecek

5

Si es su propia función en lugar de una de núcleo de PHP, usted podría hacer:

function foo($arguments = []) { 
    $defaults = [ 
    'an_argument' => 'a value', 
    'another_argument' => 'another value', 
    'third_argument' => 'yet another value!', 
    ]; 

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

    // now, do stuff! 
} 

foo(['another_argument' => 'not the default value!']); 
12

Si es su función, se puede utilizar null como comodín y establecer el valor predeterminado más tarde dentro de la función:

function foo($a=null, $b=null, $c=null) { 
    if (is_null($a)) { 
     $a = 'apple'; 
    } 
    if (is_null($b)) { 
     $b = 'brown'; 
    } 
    if (is_null($c)) { 
     $c = 'Capulet'; 
    } 
    echo "$a, $b, $c"; 
} 

a continuación, se pueden quitar mediante el uso de null:

foo('aardvark', null, 'Montague'); 
// output: "aarkvark, brown, Montague" 
0

Puede usar algunas peculiaridades, ya sea pasando todos los argumentos como sugiere una matriz como ceejayoz, o algún código demasiado complicado que analiza func_get_args() y se combina con una lista de valores predeterminados. Para no copiarlo y pegarlo, tendrás que usar objetos y rasgos. Finalmente, para poder pasar todo tipo de valores (sin excluir nulos o falsos al convertirlos en una señal para la sustitución de parámetros predeterminada), tendrá que declarar un tipo especial ficticio DefaultParam. Otro menos es que tiene que duplicar los nombres y los valores predeterminados en la declaración de función, si desea obtener sugerencias de tipo o ayuda en cualquier IDE.

class DefaultParam {} 

trait multi_arg_functions 
{ 
    private static function multi_arg($defaults, $list, $preserve_index = false) 
    { 
    $arg_keys = array_slice(array_keys($defaults), 0, count($list)); 

    if ($preserve_index) { 
     $listed_arguments = array_slice($list, 0, count($arg_keys)); 
     $extras = array_slice($list, count($arg_keys), null, true); 
    } else { 
     $listed_arguments = array_splice($list, 0, count($arg_keys)); 
     $extras = &$list; 
    } 
    unset($list); 

    $arguments = array_combine($arg_keys, $listed_arguments); 
    $arguments = array_filter($arguments, function ($entry) { 
     return !($entry instanceof DefaultParam); //remove entries that mean default, a special class in this case 
    }); 
    $arguments = array_merge($defaults, $arguments); 

    return [$arguments, $extras]; 
    } 
} 

class b { 
    use multi_arg_functions; 

    static function func1($an_argument = 'a value', $another_argument = 'another value', $third_argument = 'yet another value') { //give defaults here to get hints in an IDE 
     list($args, $extras) = self::multi_arg(//note: duplicate names and defaults 
      [ 
      'an_argument' => 'a value', 
      'another_argument' => 'another value', 
      'third_argument' => 'yet another value!', 
      ], func_get_args()); 

     echo json_encode(['args' => $args, 'extras' => $extras])."\n"; 
    } 
} 

$default_param = new DefaultParam(); 

b::func1('value 1'); 
b::func1('value 2', $default_param, 'third argument'); 
b::func1('value 3', $default_param, 'third argument', 'fourth argument'); 

Nota: utilizando preserve_index = true obtiene los argumentos adicionales para comenzar desde su índice original.

Cuestiones relacionadas