Foros del Web » Programando para Internet » PHP »

Usar elementos de arraycomo parametros de funcion

Estas en el tema de Usar elementos de arraycomo parametros de funcion en el foro de PHP en Foros del Web. Hola. Lo que intento es usar elementos de un array y pasarlos como parametros a una funcion, actualmente lo unico que se me ocurre es ...
  #1 (permalink)  
Antiguo 20/05/2016, 22:53
Avatar de Atomycko  
Fecha de Ingreso: diciembre-2005
Ubicación: Zapopan Jal.
Mensajes: 92
Antigüedad: 18 años, 4 meses
Puntos: 12
Usar elementos de arraycomo parametros de funcion

Hola.

Lo que intento es usar elementos de un array y pasarlos como parametros a una funcion, actualmente lo unico que se me ocurre es usar eval, pero por mi experiencia se que este metodo no es muy confiable en cuanto a seguridad.
Espero poder explicarme mejor con este ejemplo de como lo hago con eval.
Código:
// Nombre de la funcion
$fnc = 'mi_funcion';

// Array el cual contiene los parametros a ser pasados a la funcion
$ary = array('a', 'b', 'c');

// Se comprueba la existencia de la funcion a llamar
if(function_exists($fnc)){
    // Si el array de parametros esta vacio solo se llama a la funcion
    if(empty($ary)){
        $fnc();
    }
    else{
        // Aqui esta lo rudo...
        @eval("$fnc(\$ary['" . implode("'],\$ary['", array_keys($ary)) . "']);");
    }
}
Bueno, espero que me haya explicado y que puedan ayudarme, de antemano gracias.

Saludos!
__________________
PD: Los acentos fueron secuestrados.
  #2 (permalink)  
Antiguo 20/05/2016, 23:09
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Usar elementos de arraycomo parametros de funcion

Jamás uses eval(), eso es lo peor que puedes hacer.

En tu caso debes usar call_user_func_array(), consulta el manual.
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #3 (permalink)  
Antiguo 21/05/2016, 00:21
Avatar de Atomycko  
Fecha de Ingreso: diciembre-2005
Ubicación: Zapopan Jal.
Mensajes: 92
Antigüedad: 18 años, 4 meses
Puntos: 12
Respuesta: Usar elementos de arraycomo parametros de funcion

Saludos pateketrueke!

Gracias por el dato de esta funcion, solo que en realidad lo que intento hacer es cargar clases desde otra clase, aun que si me funciono usando call_user_func_array, solo que ahora tengo que asegurarme que las clases tengan los valores por defecto en los parametros del constructor, pero por lo menos me libre del eval.

El codigo quedo mas o menos asi.
Código PHP:
class Mi_Clase_Principal{
    var 
$clases = array();
    function 
clase($clase$parametros = array(), $nueva false){
        if(isset(
$this->clases[$clase]) && !$nueva){
            return 
$this->clases[$clase];
        }
        if(!
class_exists($clase)){
            
$archivo DIRECTORIO_DE_ARCHIVOS_DE_CLASES 'clase_' $clase '.php';
            if(!
file_exists($archivo)){
                exit(
"El archivo de la clase '$clase' no existe");
            }
            include(
$archivo);
        }
        if(
class_exists($clase)){
            
$instancia = new $clase;
            if(!empty(
$parametros) && method_exists($instancia'__construct')){
                
call_user_func_array(array($instancia'__construct'), $parametros);
            }
            
$this->clases[$clase] = $instancia;
            return 
$this->clases[$clase];
        }
        exit(
"La clase '$clase' no existe");
    }

Aunque por el momento parece estar solucionado, se aceptan opiniones.

Saludos!
__________________
PD: Los acentos fueron secuestrados.
  #4 (permalink)  
Antiguo 21/05/2016, 19:49
Avatar de hhs
hhs
Colaborador
 
Fecha de Ingreso: junio-2013
Ubicación: México
Mensajes: 2.995
Antigüedad: 10 años, 10 meses
Puntos: 379
Respuesta: Usar elementos de arraycomo parametros de funcion

Por lo que veo, estas haciendo una clase que te ayude a cargar e instanciar otras clases, pero creo que te estas haciendo un lío ya que puedes usar la función spl_autoload_register que precisamente te permite cargar clases cuando haces referencia a ellas, te dejo un ejemplo:
Código PHP:
Ver original
  1. <?php
  2. //Ojo este ejemplo es muy sencillo y es solo para explicar
  3. spl_autoload_register(function($class){
  4.     $file = sprintf('%s/lib/%s.php',__DIR__, $class);
  5.  
  6.     if(file_exists($file)) {
  7.         require_once($file);
  8.     } else {
  9.         throw new Exception("Cant load file: $file");
  10.     }
  11.    
  12. });
  13.  
  14. //Instanciar clase qie se encuentra en la carpeta lib/
  15. try{
  16.     $class = new A();
  17.     $class->display();
  18. }catch (Exception $e) {
  19.     echo $e->getMessage();
  20. }
Cuando tu intentas crear una nueva instancia spl_autoload_register intenta buscar un archivo que tiene el nombre de la clase, de fallar lanza un excepción. En nuestro ejemplo intenta instanciar la clase A que tiene como archivo A.php.

Con esto tu puedes simplificar tu clase a esto:
Código PHP:
Ver original
  1. class Mi_Clase_Principal{
  2.    
  3.     private $clases = array();
  4.    
  5.     function clase($clase, $parametros = array()){
  6.         if(isset($this->clases[$clase]) && in_array($clase, $this->clases[$clase])){
  7.             return $this->clases[$clase];
  8.         }
  9.  
  10.         if(class_exists($clase)){
  11.             $instancia = new $clase;
  12.             if(!empty($parametros) && method_exists($instancia, '__construct')){
  13.                 call_user_func_array(array($instancia, '__construct'), $parametros);
  14.             }
  15.             $this->clases[$clase] = $instancia;
  16.             return $this->clases[$clase];
  17.         }
  18.         exit("La clase '$clase' no existe");
  19.     }
  20. }
El cuerpo de la segunda condición no requiere que compruebes si existe el constructor si agregaste parametros por defecto en la clase que estas queriendo instanciar, así que puedes hacer algo como lo siguiente
Código PHP:
Ver original
  1. class Mi_Clase_Principal{
  2.  
  3.     private $clases = array();
  4.  
  5.     function clase($clase, $parametros = array()){
  6.  
  7.         if(isset($this->clases[$clase]) && in_array($clase, $this->clases[$clase])){
  8.             return $this->clases[$clase];
  9.         }
  10.  
  11.         if(class_exists($clase)){
  12.             $instancia = (empty($parametros)) ? new $clase : new $clase(...$parametros);
  13.  
  14.             $this->clases[$clase] = $instancia;
  15.  
  16.             return $this->clases[$clase];
  17.         }
  18.  
  19.         throw new Exception("La clase $clase no existe");
  20.     }
  21. }
Si mueves tu clase a un directorio lib como en nuestro ejemplo y creas una clase para probar; en mi ejemplo mi clase es de esta forma:
Código PHP:
Ver original
  1. //archivo A.php en lib/
  2. class A {
  3.    
  4.     private $x;
  5.    
  6.     private $y;
  7.  
  8.     public function __construct($x = 'hola', $y = 'mundo')
  9.     {
  10.         $this->x = $x;
  11.         $this->y = $y;
  12.     }
  13.    
  14.     public function display()
  15.     {
  16.         echo "$this->x $this->y";
  17.     }
  18. }
Y juntamos todo, nuestro ejemplo puede quedar algo como esto
Código PHP:
Ver original
  1. spl_autoload_register(function($class){
  2.     $file = sprintf('%s/lib/%s.php',__DIR__, $class);
  3.  
  4.     if(file_exists($file)) {
  5.         require_once($file);
  6.     } else {
  7.         throw new Exception("Cant load file: $file");
  8.     }
  9.    
  10. });
  11.  
  12. //Instanciar clase qie se encuentra en la carpeta lib/
  13. try{
  14.     $cp = new Mi_Clase_Principal();
  15.  
  16.     $instancias = $cp->clase('A', [1, 2]);
  17.  
  18.     print_r($instancias->display());
  19.  
  20. }catch (Exception $e) {
  21.  
  22.     echo $e->getMessage();
  23.  
  24. }
Espero que el ejemplo te haya ayudado, lo siguiente es que ahora hagas tu propia implementación de autoloading y que mejores la clase Mi_Clase_Principal.
__________________
Saludos
About me
Laraveles
A class should have only one reason to change.

Etiquetas: elementos, funcion, parametros, usar
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 02:00.