script - Función PHP con número ilimitado de parámetros.
php script command line arguments example (8)
¿Has echado un vistazo a func_get_args , func_get_arg y func_num_args
Así por ejemplo:
function foo(){
if ( func_num_args() > 0 ){
var_dump(func_get_args());
}
}
o:
function bind_param(){
if ( func_num_args() <= 1 ){
return false; //not enough args
}
$format = func_get_arg(0)
$args = array_slice(func_get_args(), 1)
//etc
}
EDITAR
Respecto al comentario de Ewan Todds:
No tengo ningún conocimiento de la API base para la que está creando el contenedor, pero otra alternativa puede ser hacer algo con las funciones de encadenamiento para que la interfaz resultante se parezca a algo como:
$var->bind()->bindString($code)
->bindString($language)
->bindString($official)
->bindDecimal($percent);
Lo cual preferiría sobre el uso de func_get_args, ya que el código es probablemente más legible y, lo que es más importante, causa errores debido a la falta de una variable de formato.
¿Cómo escribo una función que pueda aceptar un número ilimitado de parámetros?
Lo que estoy tratando de hacer es crear una función dentro de una clase que incluya lo siguiente:
$stmt->bind_param(''sssd'', $code, $language, $official, $percent);
Anteriormente, debería haber utilizado func_get_args()
, pero en el php 5.6 , puede usar ... el operador .
Entonces, por ejemplo, puede escribir la función que le devuelve una suma de todos los números, enviados a la función:
function bind_param(...$params){
var_dump($params);
}
Tus params
son en realidad una matriz de todos los elementos.
Con 5 parámetros, este diseño está comenzando a mostrar el " Demasiados parámetros " de AntiPattern. Esto sugiere la refactorización denominada Objeto de parámetro , un objeto o estructura con miembros de datos que representan los argumentos que se pasarán. Sin embargo, evite convertirlo en un contenedor mágico .
Consulte también Presentar refactorización de objetos de parámetros en refactoring.com.
Hay una función llamada func_get_args() que es una matriz de todos los argumentos pasados a la función.
Ejemplo de PHP.net
function foo()
{
$numargs = func_num_args();
echo "Number of arguments: $numargs<br />/n";
if ($numargs >= 2) {
echo "Second argument is: " . func_get_arg(1) . "<br />/n";
}
$arg_list = func_get_args();
for ($i = 0; $i < $numargs; $i++) {
echo "Argument $i is: " . $arg_list[$i] . "<br />/n";
}
}
foo(1, 2, 3);
El ejemplo anterior dará como resultado:
Número de argumentos: 3
El segundo argumento es: 2
Argumento 0 es: 1
Argumento 1 es: 2
El argumento 2 es: 3
Las respuestas con func_get_args () funcionarán bien para parámetros que no sean de referencia. Sin embargo, hay un truco para que los parámetros pasados por referencia funcionen. Además, técnicamente no es una función que acepta parámetros ilimitados , sino simplemente un número arbitrariamente grande, por ejemplo, cien.
Lo que puede hacer, es definir una función que tome una gran cantidad de argumentos, y hacer que estén predeterminados en nulo. Luego, dentro de esa función, agregue cada referencia no nula a una matriz, que luego se usaría para llamar a * bind_param () * usando * call_user_func_array () *.
function my_bind_param(&$stmt, $types, &$arg1, &$arg2 = null, &$arg3 = null, ...)
{
$vars = array($types);
$vars[] = $arg1;
if ($arg2 != null)
$vars[] = &$arg2;
if ($arg3 != null)
$vars[] = &$arg3;
...
if (!call_user_func_array(array($stmt, "bind_param"), $vars))
{
if ($stmt->errno == 0)
return array(-1, "Unknown error binding parameters.");
else
return array(-1, "Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error);
}
return array(0, "");
}
El verdadero truco es que no quieres escribir esto a mano. Simplemente haga otra secuencia de comandos que genere el cuerpo de esta función (todo entre los soportes de garabatos) como * my_bind_param_body.php *. Luego, simplemente defina el encabezado de la función en su archivo principal e incluya el cuerpo en esa definición de función. es decir
function my_bind_param(&$stmt, $types, &$arg1, &$arg2 = null, &$arg3 = null, ...)
{
return include "my_bind_param_wrapper_body.php";
}
Lo anterior sugiere que todo está bien, pero no creo que sean adecuados para su situación.
$stmt->bind_param(''sssd'', $code, $language, $official, $percent);
Si desea ajustar esta función, deberá pasar referencias a las variables de argumento originales a la función bind_param. No creo que func_get_args () te dé esto, te da valores en su lugar. Por lo tanto, no será posible utilizarlos para pasar a la función principal. Luché contra un problema similar cuando intenté extender mysqli_stmt y nunca llegué a una solución satisfactoria.
Me temo que esta no es realmente una respuesta a su pregunta, solo una advertencia de que otros argumentos pueden no funcionar en su aplicación particular de un número arbitrario de argumentos.
Si está utilizando PHP 5.6 o una versión posterior, las listas de argumentos pueden incluir el token ...
para indicar que la función acepta un número variable de argumentos. Los argumentos se pasarán a la variable dada como una matriz; Simplemente utilizando ...
puedes acceder a argumentos variables ilimitados.
por ejemplo:
<?php
function sum(...$numbers) {
$sum = 0;
foreach ($numbers as $n) {
$sum += $n;
}
return $sum ;
}
echo sum(1, 2, 3, 4, 5);
?>
Si está utilizando la versión de PHP <= 5.5 , puede acceder a un parámetro ilimitado func_num_args las func_num_args , func_get_arg y func_get_args() .
Por ejemplo:
<?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);
?>
Utilice func_get_args()
:
function my_func() {
$args = func_get_args();
foreach ($args as $arg) {
echo "Arg: $arg/n";
}
}