2011-01-02 16 views
7

En Python y otros, hay una sintaxis especial para listas de argumentos de longitud variable:PHP argumentos de longitud variable?

def do_something(*args): 
    # do something 

do_something(1, 2, 3, 4, 5, ...) # arbitrarily long list 

estaba leyendo el manual de PHP, y dijo lo siguiente:

PHP 4 y superior tiene soporte para variables -length lista de argumentos en funciones definidas por el usuario. Esto es realmente bastante fácil, utilizando las funciones func_num_args(), func_get_arg() y func_get_args() .

Sin sintaxis especial se requiere, y listas de parámetros pueden ser explícitamente provisto de definiciones de funciones y se comportará de forma normal.

Obtengo la primera parte. Puedes pasar tantos argumentos como desees a una función que no tenga argumentos, y luego obtenerlos como una matriz usando func_get_args(), etc. Sin embargo, realmente no entiendo lo que dice la segunda parte.

Entonces, mi pregunta es, ¿hay alguna sintaxis especial para los argumentos de longitud variable, o alguna mejor práctica que yo desconozca? El enfoque que el manual sugiere parece kludgey en el mejor de los casos y hace que su función parezca que no está tomando argumentos (a menos que lo esté haciendo mal). ¿No debería tratar de usar esta función de idioma en absoluto?

+7

@Shrapnel que es una especie de filosofía de PHP, ¿no? ¿A quién le importan los demás, solo produciré lo que sea? –

+1

PHP admite comentarios. Eso es suficiente. Si desea codificar, no * parchar * sobre el código. –

Respuesta

10

A diferencia del operador * de Python o la palabra clave params de C#, ni siquiera tiene que especificar los argumentos de longitud variable. A medida que la segunda parte comienza, "No se requiere sintaxis especial".

En cuanto al resto del segundo párrafo: si desea especificar cualquier argumento requerido o no relacionado que venga antes de los argumentos de longitud variable, especifíquelos en su firma de función para que su función pueda manejarlos. Luego, para obtener los argumentos de longitud variable, retire las variables requeridas de func_get_args(), así:

function func($required) { 
    // Contains all arguments that come after $required 
    // as they were present at call time 
    $args = array_slice(func_get_args(), 1); 
} 

Usted no tiene que hacer esto (aún se puede cortar a partir func_get_args() y utilizar sus diferentes elementos en consecuencia), pero hace que su código sea más autodocumentado.

+1

Estaba pensando más en tener un nombre para los argumentos de longitud variable, pero gracias, esta es información útil. –

+0

Es un patrón genial pero 'array_slice (func_get_args(), 1)' lanzará una advertencia en PHP 5.3 y un error fatal en 5.4 http://bd.php.net/manual/en/language.references.pass.php - la solución es envolver 'funct_get_args()' entre paréntesis como 'array_splice ((func_get_args()), 1)' –

2

No hay una sintaxis especial para las funciones de argumento de longitud variable.

Simplemente use las funciones func_num_args() y func_get_args() para obtener los argumentos.

Ejemplo:

function callMe(){ 

    if(func_num_args() == 0){ 
     echo 'No arguments =)'; 
    }else{ 
     var_dump(func_get_args()); 
    } 

} 
+0

+1 para un buen ejemplo :) – nepsdotin

0

que suele hacer esto para evitar mantenido función de cambio, y evitar el error en orden de los argumentos

function any_function($ops=array()) 
{ 
} 

$ops = array('name'=>1, 'type'=>'simplexml', 'callback'=>...); 
+2

Bueno, también pierdes el beneficio de obtener un error si el usuario pasa los argumentos incorrectos - o escribe mal uno de los argumentos. pros y contras. – troelskn

+0

No diría que no es cierto, preferiría la clave asociada que debería ser más legible para indexar la clave – ajreal

+0

Personalmente, odio instalar arreglos en las funciones. es demasiado largo para escribir todos estos delimitadores –

18

Aquí está un ejemplo más realista:

function Average() 
{ 
    $result = 0; 
    $arguments = func_get_args(); 

    foreach ($arguments as $argument) 
    { 
     $result += $argument; 
    } 

    return ($result/max(1, func_num_args())); 
} 

Average(1, 2, 3, 4, 5); // 3 

Esto se llama variadic function.

+9

+1 para la terminología correcta. –

1

La segunda parte es básicamente diciendo que una vez que empiece a usar las funciones de argumentos variables, entonces

function average() { ... } 
function average(arg1, arg2, arg3) { ... } 

trabajo de forma idéntica, sólo que la segunda versión tiene 3 argumentos explícitamente enumerados. Eso es todo, no intente leer más en una página man que la que hay.

6

Desde PHP 5.6, se puede especificar una lista de argumentos variables con el operador ....

function do_something($first, ...$all_the_others) 
{ 
    var_dump($first); 
    var_dump($all_the_others); 
} 

do_something('this goes in first', 2, 3, 4, 5); 

#> string(18) "this goes in first" 
#> 
#> array(4) { 
#> [0]=> 
#> int(2) 
#> [1]=> 
#> int(3) 
#> [2]=> 
#> int(4) 
#> [3]=> 
#> int(5) 
#> } 

Como se puede ver, el operador ... recoge la lista variable de argumentos en una matriz.

Si necesita pasar los argumentos variables a otra función, la ... puede ayudarlo.

function do_something($first, ...$all_the_others) 
{ 
    do_something_else($first, ...$all_the_others); 
    // Which is translated to: 
    // do_something_else('this goes in first', 2, 3, 4, 5); 
} 

Desde PHP 7, la lista de variables de argumentos puede ser forzado a ser todo del mismo tipo también.

function do_something($first, int ...$all_the_others) { /**/ } 
Cuestiones relacionadas