2011-03-11 11 views
18

Acabo de descubrir que hay una función llamada func_get_arg en PHP que permite al desarrollador usar el estilo de variante para obtener argumentos. Parece ser muy útil porque el número de argumentos ahora puede ser arbitrario, pero no se me ocurre ningún buen ejemplo de su uso.¿Cuál es el buen ejemplo de usar 'func_get_arg' en PHP?

¿Cuáles son algunos ejemplos del uso de esta función para aprovechar al máximo su característica polimórfica?

+0

http://us2.php.net/manual/en/function.func-get-arg.php Desplácese hasta 'Examples', luego lea' User Contributed Notes' – drudge

+0

'sprintf' y' max' son buenas ejemplos de funciones que pueden tratar con una cantidad arbitraria de argumentos. Por lo general, desea usarlo con parámetros escritos uniformemente. – mario

+4

No quiere decir 'polimórfico': el término que está buscando es 'variadic': http://en.wikipedia.org/wiki/Variadic_function –

Respuesta

22

Normalmente uso func_get_args(), que es más fácil de usar si se desean múltiples argumentos.

Por ejemplo, para volver a crear el max() de PHP.

function max() { 
    $max = -PHP_INT_MAX; 
    foreach(func_get_args() as $arg) { 
     if ($arg > $max) { 
      $max = $arg; 
     } 
    } 
    return $max; 
} 

CodePad.

Ahora puede hacer echo max(1,5,7,3) y obtener 7.

+4

Ya sabe, puede reducir, si perdona el juego de palabras , hasta 'array_reduce (func_get_args(), 'max')', y funcionará también con números negativos. –

+0

@Keith Tal vez debería haber hecho ese número inicial '-PHP_INT_MAX'. – alex

+1

El único problema es que si no se le dan argumentos, la respuesta es '-PHP_INT_MAX'. 'array_reduce ($ a, 'max')' funcionará incluso para una matriz vacía, en cuyo caso devolverá 'null'. Estamos un poco fuera del tema aquí.:-) –

1

Casi nunca uso func_get_arg(), pero uso su primo func_get_args() bastante. Aquí está un ejemplo, una función a lo largo de las líneas de la cuenta echo esa entidad codifica todos sus argumentos:

function ee() { 
    $args = func_get_args(); 
    echo implode('', array_map('htmlentities', $args)); 
} 

uso esa función un poco.

Aquí hay otro ejemplo útil, una función que realiza el mismo trabajo que la función COALESCE() de SQL.

function coalesce() { 
    $args = func_get_args(); 
    foreach ($args as $arg) { 
     if (!is_null($arg)) { 
      return $arg; 
     } 
    } 
    return null; 
} 

Devuelve el primer argumento no es nulo aprobada en, o null si no hay tal argumento.

+2

[Puede eliminar ese primer argumento] (http://codepad.org/Gil0Xi29) a 'implode()'. – alex

+3

Fuerza del hábito: he estado escribiendo código en PHP desde poco después de que apareció PHP 4.0. –

1

Personalmente, no creo que haya un buen caso de uso dentro de una función normal. Como fanático del control, me gusta saber exactamente qué se está pasando a mis funciones y me gustaría saber exactamente lo que estoy pasando.

Sin embargo, se puede utilizar por completo para cosas como el enrutamiento dinámico/estático de URL. Cuando estás reescribiendo (a través de mod_rewrite) la URL args a un solo arranque.

En este sentido, puede tener argumentos que no necesariamente tienen que existir con cada solicitud de página.

2

En primer lugar, está utilizando el término "polimorfismo" totalmente equivocado. El polimorfismo es un concepto en la programación orientada a objetos, y no tiene nada que ver con la cantidad variable de argumentos en las funciones.

En mi experiencia, todo lo que func_get_args le permite hacer es agregar un poco de azúcar sintáctico.

Piense en una función que puede tomar cualquier número entero y devolver su suma. (Estoy haciendo trampa, como esto ya existe en array_sum. Pero copiar es bueno si mantiene el ejemplo simple). Se podía hacerlo de esta manera:

// you can leave "array" out; I have it because we should be getting one here 
function sum1(array $integers) { 
    return array_sum($integers); 
} 

Ahora se llamarían a esto, así:

$sum = sum1(array(1)); 
$sum = sum1(array(1, 2, 3, 4)); 

Esto no es muy bonita.Pero podemos hacer mejor:

function sum2() { 
    $integers = func_get_args(); 
    return array_sum($integers); 
} 

Ahora se le puede llamar así:

$sum = sum2(1); 
$sum = sum2(1, 2, 3, 4); 
2

Digamos que tenemos varias matrices que contienen datos en la que tenemos que buscar a través de las claves de sus valores sin la combinación estas matrices.

Las matrices son como:

$a = array('a' => 5, 'b' => 6); 
$b = array('a' => 2, 'b' => 8); 
$c = array('a' => 7, 'b' => 3); 

En ese caso, decimos que necesitamos para obtener todos los valores de la clave a de todas las matrices. Podemos escribir una función que tome en número arbitrario de matrices para buscar en

// we need the key, and at least 1 array to search in 
function simpleSearchArrays($key, $a1){ 
    $arrays = func_get_args(); 
    array_shift($arrays); // remove the first argument, which is the key 
    $ret = array(); 
    foreach($arrays as $a){ 
     if(array_key_exists($key, $a)){ 
      $ret[] = $a[$key]; 
     } 
    } 
    return $ret; 
} 

Así que si usamos la función:.

$x = simpleSearchArrays('a', $a, $b, $c); 

$x contendrá entonces array(5, 2, 7).

0

Lea el documento oficial y descubra que func_get_args():
Obtiene una matriz de la lista de argumentos de la función.

Esta función se puede usar junto con func_get_arg() y func_num_args() para permitir que las funciones definidas por el usuario acepten listas de argumentos de longitud variable.

<?php 
     function foo() 
     { 
      $numargs = func_num_args(); 
      echo "Number of arguments: $numargs \n"; 
      if ($numargs >= 2) { 
       echo "Second argument is: " . func_get_arg(1) . "\n"; 
      } 
      $arg_list = func_get_args(); 
      for ($i = 0; $i < $numargs; $i++) { 
       echo "Argument $i is: " . $arg_list[$i] . "\n"; 
      } 
     } 

     foo(1, 2, 3); 
?> 
0

A partir de php5.6, no es un caso de uso de func_get_arg más; Lo cual no quiere decir que su funcionalidad ya no es necesaria, pero se sustituye por el variadic function utilizando la sintaxis ...:

/** 
* @param array $arguments 
*/ 
public function poit(...$arguments) 
{ 
    foreach($arguments as $argument) { 
     ... 
    } 
} 

Esto es especialmente útil si hay métodos que se sobrecargan al final; uno no necesita filtrar los primeros argumentos más, ya exhibido por an example:

viejo estilo usando func_get_arg:

function foo($a, $b) { 
    $c = array(); 
    if (func_num_args() > 2) { 
     for($i = 0; $i < func_num_args()-2; $i++) { 
      $c[] = func_get_arg($i+2); 
     } 
    } 
    var_dump($a, $b, $c) 
    // Do something 
} 
foo('a', 'b', 'c', 'd'); 

reciente estilo variadic;

function foo($a, $b, …$c) { 
    var_dump($a, $b, $c); 
    // Do something 
} 
foo('a', 'b', 'c', 'd'); 

Ambos foo producen la misma salida, uno es mucho más simple de escribir.

Cuestiones relacionadas