Estoy confundido acerca de los valores predeterminados para las funciones de PHP. Digamos que tengo una función como esta:
function foo($blah, $x = "some value", $y = "some other value") {
// code here!
}
¿Qué sucede si quiero usar el argumento predeterminado para $ x y establecer un argumento diferente para $ y?
He estado experimentando con diferentes formas y me estoy confundiendo cada vez más. Por ejemplo, probé estos dos:
foo("blah", null, "test");
foo("blah", "", "test");
Pero ambos no dan como resultado un argumento predeterminado adecuado para $ x. También he intentado configurarlo por nombre de variable.
foo("blah", $x, $y = "test");
Esperaba que algo así funcionara. Pero no funciona como esperaba en absoluto. Parece que no importa lo que haga, tendré que terminar escribiendo los argumentos predeterminados de todos modos, cada vez que invoque la función. Y debo estar perdiendo algo obvio.
foo("blah", , "test");
?Respuestas:
Propondría cambiar la declaración de función de la siguiente manera para que pueda hacer lo que quiera:
De esta manera, puede realizar una llamada como
foo('blah', null, 'non-default y value');
y hacer que funcione como desee, donde el segundo parámetro$x
aún obtiene su valor predeterminado.Con este método, pasar un valor nulo significa que desea el valor predeterminado para un parámetro cuando desea anular el valor predeterminado para un parámetro que viene después.
Como se indicó en otras respuestas,
Si tengo un método que puede aceptar un número variable de parámetros y parámetros de diferentes tipos, a menudo declaro la función similar a la respuesta mostrada por Ryan P.
Aquí hay otro ejemplo (esto no responde a su pregunta, pero es de esperar informativo:
fuente
null
valor real al parámetro, ya que cada vez asignaría el valor predeterminado. Incluso en el caso de que tuviera otro valor especial para cuando realmente desea un valor nulo (por ejemplo, cuando $ x == "use_null" hace $ x = nulo), entonces no podrá asignar un valor tan especial como el valor literal de parámetro (en este caso, la cadena "use_null"). Así que asegúrese de usar una "clave" única y nunca deseada para cuando quiera usar el valor predeterminado (y quieranull
ser una opción válida)Los argumentos opcionales solo funcionan al final de una llamada de función. No hay forma de especificar un valor para $ y en su función sin especificar también $ x. Algunos idiomas admiten esto mediante parámetros con nombre (VB / C #, por ejemplo), pero no PHP.
Puede emular esto si usa una matriz asociativa para parámetros en lugar de argumentos, es decir
Luego llame a la función así:
fuente
isset($args['x'])
, ya que actualmente reemplazaría una cadena vacía, una matriz vacía ofalse
con el valor predeterminado.$x = !array_key_exists('x',$args) ? 'default x value' : $args['x'];
En realidad es posible:
Si quieres hacerlo es otra historia :)
ACTUALIZAR:
Las razones para evitar esta solución son:
Pero en realidad puede ser útil en situaciones donde:
no quieres / no puedes cambiar la función original.
podrías cambiar la función pero:
null
(o equivalente) no es una opción (ver el comentario de DiegoDD )func_num_args()
Sobre el rendimiento, una prueba muy simple muestra que el uso de la API de Reflection para obtener los parámetros predeterminados hace que la llamada a la función sea 25 veces más lenta , mientras que todavía toma menos de un microsegundo . Debes saber si puedes vivir con eso.
Por supuesto, si quiere usarlo en un bucle, debe obtener el valor predeterminado de antemano.
fuente
fuente
$defaults = [ 'x' => 'some value', 'y' => 'some other value'];
La única manera que sé de hacerlo es omitiendo el parámetro. La única forma de omitir el parámetro es reorganizar la lista de parámetros para que el que desea omitir sea después de los parámetros que DEBE configurar. Por ejemplo:
Entonces puedes llamar a foo como:
Esto resultará en:
fuente
Recientemente tuve este problema y encontré esta pregunta y respuestas. Si bien las preguntas anteriores funcionan, el problema es que no muestran los valores predeterminados a los IDE que lo admiten (como PHPStorm).
si lo usa
null
, no sabrá cuál sería el valor si lo deja en blanco.La solución que prefiero es poner el valor predeterminado en la definición de la función también:
La única diferencia es que necesito asegurarme de que sean iguales, pero creo que es un pequeño precio a pagar por la claridad adicional.
fuente
No puede hacer esto directamente, pero un poco de violín de código hace posible emular.
fuente
null
en este caso es conceptualmente más ordenado quefalse
.false
es una opción más arriesgada quenull
, porque php es un lenguaje no estricto.!$x
será cierto para varias entradas diferentes, que pueden sorprender al programador:0
,''
. Mientras que connull
, puede utilizar!isset
como una prueba más estricta.fuente
Mis 2 centavos con operador de fusión nulo
??
(desde PHP 7)Puedes consultar más ejemplos en mi repl.it
fuente
Este es el caso, cuando los objetos son mejores, porque puede configurar su objeto para mantener x e y, configurar valores predeterminados, etc.
El enfoque con la matriz está cerca para crear el objeto (de hecho, el objeto es un grupo de parámetros y funciones que funcionarán sobre el objeto, y la función que toma la matriz funcionará sobre algunos parámetros del grupo)
Es cierto que siempre puedes hacer algunos trucos para establecer nulo o algo así como predeterminado
fuente
También puede verificar si tiene una cadena vacía como argumento para que pueda llamar como:
foo('blah', "", 'non-default y value', null);
Debajo de la función:
No importa si llena
null
o""
, todavía obtendrá el mismo resultado.fuente
Pase una matriz a la función, en lugar de parámetros individuales y use un operador de fusión nulo (PHP 7+).
A continuación, paso una matriz con 2 elementos. Dentro de la función, estoy verificando si el valor para el elemento 1 está configurado, si no se asigna la bóveda predeterminada.
fuente
$args['item1'] = $args['item1']??'default value';
en PHP 7+. si $ args ['item1'] es nulo, ladefault value
cadena se asignará a $ args ['item1']