Comunidad de diseño web y desarrollo en internet online

Análisis y extensión de clases en PHP con ReflectionMethod

Reflection es una clase o más bien un conjunto de clases de PHP que permiten saber todo sobre tus otras clases, métodos, funciones, parametros, etcétera... Quizás es una de las funcionalidades más c00l :cool: que PHP ha agregado recientemente y quizás una de las que menos se conoce o se usa: ReflectionMethod.

Por acá les dejo un código que me pareció bastante práctico y su siguiente explicación:

Supongamos que necesitan llamar a un método de una clase (un controlador o algo así) usando call_user_func_array desde alguna parte de nuestro script, pero antes de llamarlo directamente, quieren validar que:

  1. El método a llamar sea público
  2. La cantidad de parámetros enviados no es menor que la cantidad de parámetros requeridos por el método.

Y adicionalmente les gustaría no sólo pasar los parámetros como parámetros ordinarios, sino también tenerlos disponibles en una clase aparte, es decir, que al llamar a una función como:

Código :

function verLista($year, $month)


Con los siguientes valores:

Código :

call_user_func_array(array($controller, 'verLista'), array(2008, 10));


Permita generar en el Controller un objeto con los siguientes valores:

Código :

$this->params->year = 2008;
$this->params->month = 10;


Lo cual tal vez sería util si más adelante se necesita pasar estos valores de un método a otro dentro del controlador sin necesidad del uso de parámetros y si se quiere agregar una seguridad extra al script (como bloquear la posibilidad de sobreescribir o reemplazar parametros)

En fin, esta es la idea.. Aquí el código:

Primeramente tenemos una clase básica llamada ControllerParams que permite guardar y obtener datos / parámetros:

Código :

class ControllerParams
{
   
   private $params = array();
   
   function __set($name, $value)
   {
      $this->params[$name] = $value;
   }
   
   function __get($name)
   {
      return $this->params[$name];
   }
   
}


Y aquí el método que hace la funcionalidad ya descripta:

Código :


class Controller
{

        protected $params = null;

   final function execute($action, $params = null) //funcion intermedia
   {
      
      $reflectionMethod = new ReflectionMethod($this, $action); //se crea una instancia de ReflectionMethod con la referencia al metodo que necesitamos llamar

//asi ya tenemos disponible las funcionalidades de ReflectionMethod:
      
      if(($action == 'execute') || !$reflectionMethod->isPublic() || (count($params) < $reflectionMethod->getNumberOfRequiredParameters()))
      {
         //LANZAR ERROR
      }
            
      $parametros = $reflectionMethod->getParameters(); //con esto obtenemos los parametros de nuestro metodo
      
      $this->params = new ControllerParams();
      
      foreach($parameters as $key => $parameter) //y hacemos un ciclo con ellos
      {
         $name = $parameter->getName(); //obtenemos el nombre

         if(isset($params[$key])) //si el usuario mandó algun valor lo asignamos
         {
            $this->params->$name = $params[$key];
         }
         else
         {
            $this->params->$name = $parameter->getDefaultValue(); //sino tambien podemos tomar el valor por defecto
         }

      }
      
      call_user_func_array(array(&$this,   $action),   $params); //y por ultimo hacemos el llamado de costumbre
       }

}


Nótese que los parametros son también objetos con funcionalidades ^^...

Espero que el código o la explicación le sirva a alguien y no hubiese sido preferible usar el tiempo viendo alguna serie mala en sony :lol:

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Publica tu comentario

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate