Foros del Web » Programando para Internet » PHP »

Parametros por defecto de los parametros por defecto

Estas en el tema de Parametros por defecto de los parametros por defecto en el foro de PHP en Foros del Web. EL titulo es enroscado. me explico, tengo una funcion que recibe parametros de forma opcional, a su vez estos parametros son pasados a otra funcion ...
  #1 (permalink)  
Antiguo 10/10/2013, 20:57
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 11 años, 11 meses
Puntos: 320
Parametros por defecto de los parametros por defecto

EL titulo es enroscado. me explico, tengo una funcion que recibe parametros de forma opcional, a su vez estos parametros son pasados a otra funcion que los recibe como opcionales.

seria:
Código PHP:
Ver original
  1. function funcionA($parA = 'Hola' , $parB = 'Pepe') {
  2.     echo('1 Parametro: '.$parA.' | Otro parametro:'.$parB);
  3. }
  4.  
  5. function funcionB($parA , $parB = NULL , $parC = NULL) {
  6.     echo('Parametro obligatorio: '.$parA);
  7.     funcionA($parB , $parC);
  8. }
  9.  
  10. funcionB('Epaaa');

en este caso, la salida que yo espero (o que quiero obtener) es:

Cita:
Parametro obligatorio: Epaaa 1 Parametro: Hola ' | Otro parametro:Pepe
osea, que se si los parametros no son especificados se mantengan los valores por default. ¿Como puedo lograr esto sin usar 15 condicionales IF de forma super rustica?
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios
  #2 (permalink)  
Antiguo 10/10/2013, 21:21
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Parametros por defecto de los parametros por defecto

El problema con tu ejemplo es que justo en el momento en que pasas argumentos, aunque estos no contengan nada, están tomando el lugar de los parámetros opcionales volviéndolos obsoletos.

Ahora, un buen truco de programación funcional sería usar call_user_func_array(), que toma el nombre de una función (o un closure) y el arreglo toma parte de argumentos.

Si algún argumento quieres omitir entonces lo quitas del array.

Código PHP:
Ver original
  1. function funcionA($parA = 'Hola' , $parB = 'Pepe') {
  2.     echo('1 Parametro: '.$parA.' | Otro parametro:'.$parB);
  3. }
  4.      
  5. function funcionB($parA , $parB = NULL , $parC = NULL) {
  6.     echo('Parametro obligatorio: '.$parA);
  7.        
  8.     $args = func_get_args();
  9.     $args = array_filter(array_slice($args, 1));
  10.        
  11.     call_user_func_array('funcionA', $args);
  12. }
  13.      
  14. funcionB('Epaaa');

En este caso utilizo array_slice() para deshacerme del primer argumento original, y luego array_filter() para descartar los elementos vacíos.

Claro que podrías implementar algo mejor, al menos es una idea.
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #3 (permalink)  
Antiguo 10/10/2013, 21:23
Avatar de andresdzphp
Colaborador
 
Fecha de Ingreso: julio-2011
Ubicación: $this->Colombia;
Mensajes: 2.749
Antigüedad: 12 años, 9 meses
Puntos: 793
Respuesta: Parametros por defecto de los parametros por defecto

Lo más curioso es que así tienes el resultado "que quieres":

Código PHP:
Ver original
  1. function funcionA($parA = 'Hola' , $parB = 'Pepe') {
  2.     echo('1 Parametro: '.$parA.' | Otro parametro:'.$parB);
  3. }
  4.  
  5. function funcionB($parA , $parB = NULL , $parC = NULL) {
  6.     echo('Parametro obligatorio: '.$parA);
  7.     funcionA(); //<----
  8. }
  9.  
  10. funcionB('Epaaa');

Si se los pones donde te marqué te coge los 2 NULL.
__________________
Si sabemos como leer e interpretar el manual será mucho más fácil aprender PHP. En lugar de confiar en ejemplos o copiar y pegar - PHP
  #4 (permalink)  
Antiguo 10/10/2013, 21:35
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 11 años, 11 meses
Puntos: 320
Respuesta: Parametros por defecto de los parametros por defecto

pateketrueke interesante solucion pero me surgen algunas dudas
andresdzphp en verdad tu codigo hace "lo que quiero" pero no de la forma que quiero.

supongance (ambos) que a la funcion la llamo de esta manera:
funcionB('Epaaa' , 'Ehhh'); o de esta otra: funcionB('Epaaa' , , 'Ehhh');

el objetivo es que el parametro 'Ehhh' se propague a la funcionA en la posicion indicada, en el codigo de andresdzphp es obvio que no va ocurrir, y en el de pateketrueke lo aria pero siempre como primer parametro (correjime si me equivoco) y, si lo quisiera pasar como segundo tendria que dejar en null la primer posicion del array y este nulo se propagaria pisando al 'Hola' que estaba por defecto. probe a en lugar de null usar empty como valor por defecto pero al runtime de php no le gusto ni miercoles la idea y me lanzo un fatal error
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios
  #5 (permalink)  
Antiguo 10/10/2013, 21:47
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Parametros por defecto de los parametros por defecto

Te sugiero leer la documentación al respecto, aún no es posible tomar determinados valores por defecto y mucho menos esquivar alguno.

La mejor solución que se me ocurre es solamente usar un argumento, a modo de array asociativo, y crear una función que tome una definición "por defecto" y vaya sobreescribiendo cada item por su valor por defecto en caso de no contar con uno adecuado.

Eso es lo que se hace regularmente en jQuery con la función $.extend, por ejemplo.

Al parecer debes ingeniártelas al respecto, mientras no exista soporte nativo para dicha problemática no hay mucho que se pueda hacer.
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #6 (permalink)  
Antiguo 11/10/2013, 07:49
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 11 años, 11 meses
Puntos: 320
Respuesta: Parametros por defecto de los parametros por defecto

Muchas gracias, e implementado la solucion del array que me sugieres, mi problema es que la funcionB es el constructor de una clase que hereda de otra cuyo constructor es la funcionA y nesesitaba llamar al constructor de la clase padre mediante parametros opcionales de clase hija.

aca publico el codigo que use por si a alguien le sirve:
Código PHP:
Ver original
  1. //Constructor de la clase padre:
  2. /**
  3.      * El orden es: servidor | usuario | clave | nombreBd | puerto.
  4.      * NULL = Valor por defecto.
  5.      *
  6.      * @param array  $conexion Variables de conexion ordenadas.
  7.     **/
  8.     public function __construct($conexion = array(NULL , NULL , NULL , NULL , NULL)) {
  9.    
  10.         if($conexion[0] == NULL)
  11.             $conexion[0] = 'localhost';
  12.            
  13.         if($conexion[1] == NULL)
  14.             $conexion[1] = 'miuser';
  15.            
  16.         if($conexion[2] == NULL)
  17.             $conexion[2] = 'mipass';
  18.            
  19.         if($conexion[3] == NULL)
  20.             $conexion[3] = 'midb';
  21.            
  22.         if($conexion[4] == NULL)
  23.             $conexion[4] = ini_get('mysqli.default_port');
  24.                
  25.         $this->_mysqli = new mysqli($conexion[0] , $conexion[1] , $conexion[2] , $conexion[3] , $conexion[4]);
  26.         if ($this->_mysqli->connect_error)
  27.             die('Ocurrio un problema conectandose a la Bd (' . $this->_mysqli->connect_errno . ') '. $this->_mysqli->connect_error);
  28.  
  29.         $this->_mysqli->set_charset('utf8');
  30.  
  31.         self::$_instancia = $this;
  32.     }
  33.  
  34. //----------------------------------
  35.  
  36. //Constructor de la clase hija:
  37. /**
  38.      *
  39.      * @param string $tabla    Contiene el nombre de la tabla de la Bd.
  40.      * @param array  $conexion Variables de conexion ordenadas.
  41.     **/
  42.     public function __construct($tabla , $conexion = array(NULL , NULL , NULL , NULL , NULL)) {
  43.         self::$_mysqliDb = new MysqliDb($conexion);
  44.         $this->_nombreTabla = $tabla;
  45.     }

de esta forma cada vez que instancio a la clase hija puedo hacerlo con datos de conexion diferentes, o sino, por defecto con los especificados ahi arriba.

Muchas gracias.
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios

Última edición por NSD; 11/10/2013 a las 08:00
  #7 (permalink)  
Antiguo 11/10/2013, 08:02
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Parametros por defecto de los parametros por defecto

Me parece que no está muy bien tu método, aunque puedas pasar valores NULL estás obligado a pasar los parámetros en orden.

Tal como lo hiciste no era necesario el array, y en dado caso sería declarar todos los argumentos como opcionales y dentro hacer el if-then-else que ahí tienes.

Yo me imaginaba algo así:

Código PHP:
Ver original
  1. public function __construct($conexion = array()) {
  2.  
  3.     $defaults = array(
  4.         'host' => 'localhost',
  5.         'user' => 'miuser',
  6.         'pass' => 'mipass',
  7.         'db' => 'midb',
  8.         'port' => ini_get('mysqli.default_port'),
  9.     );
  10.  
  11.     $params = array_merge($defaults, array_filter($conexion));
  12.  
  13.     $this->_mysqli = new mysqli($params['host'], $params['user'], $params['pass'], $params['db'], $params['port'])
  14.         or die('Ocurrio un problema conectandose a la Bd.');
  15.  
  16.     $this->_mysqli->set_charset('utf8');
  17.  
  18.     self::$_instancia = $this;
  19. }
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #8 (permalink)  
Antiguo 11/10/2013, 08:08
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 11 años, 11 meses
Puntos: 320
Respuesta: Parametros por defecto de los parametros por defecto

Oh tienes razon, debo admitir que tu alternativa tiene mas elegancia. La voy a implementar, muchas gracias.

Tambien señalo que cometi un error grande en la linea 43 del codigo que puse, en lugar de la que esta deberia ser esta:
Código PHP:
Ver original
  1. parent::__construct($conexion);
de lo contrario no tiene sentido hablar de herencia.

muchas gracias nuevamente por tu tiempo
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios

Etiquetas: defecto, parametros
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 08:39.