Advertisement
  1. Code
  2. CodeIgniter

Cómo Crear Controladores Personalizados en CodeIgniter

Scroll to top
Read Time: 9 min

Spanish (Español) translation by Rafael Chavarría (you can also view the original English article)

Trabajando como desarrollador CodeIgniter, podrías haberte topado con el concepto de una librería en enriquece la funcionalidad principal del marco de trabajo, y CodeIgniter mismo proporciona muchas librerías en el núcleo.

De manera similar, un controlador es un tipo especial de librería que te permite agregar características personalizadas para de modo que la clase de controlador personalizado actúe como una clase padre y los adaptadores sean tratados como clases hijo.

La mejor manera de entender el concepto de controladores es ver cómo se implementa el cacheo en el marco de trabajo principal de CodeIgniter. El caché principal actúa como una clase padre y extiende la clase CI_Driver_Library. Por el otro lado, terminarás encontrando clases hijo para APC, Memcached, Redis y similares, implementadas como adaptadores enchufables. Las clases hijo extiendo a la clase CI_Driver en lugar de la clase de controlador principal.

La belleza de esta aproximación es que podrías fácilmente extender la funcionalidad del controlador agregando un nuevo adaptador según sea necesario. Como es en el caso del cacheo, si necesitas agregar una estrategia personalizada de cacheo, estás a un paso de implementarla en la forma de un adaptador personalizado.

Crear un controlador personalizado en la aplicación de CodeIgniter es el objetivo del artículo de hoy. En el curso de eso, recorreremos un ejemplo del mundo real que crea un controlador MediaRenderer usado para generar los medios desde diferentes servicios como YouTube, Vimeo, y similares. Los diferentes servicios serán implementados en la forma de clases adaptador.

Configuración de Archivo

El nombre del controlador que vamos a implementar en este artículo es MediaRenderer. Echemos un vistazo rápido a la lista de archivos que son requeridos para la configuración deseada:

  • application/libraries/MediaRenderer/MediaRendererInterface.php: Es la interfaz que el adaptador necesita implementar.
  • application/config/mediarenderer.php: El archivo de configuración que contiene ajustes relacionados de nuestro controlador personalizado.
  • application/libraries/MediaRenderer/MediaRenderer.php: Es la clase que extiende a CI_Driver_Library y es usado para operar los diferentes adaptadores disponibles en la aplicación.
  • application/libraries/MediaRenderer/drivers/MediaRenderer_youtube.php: Es la clase que implementa el adaptador YouTube.
  • application/libraries/MediaRenderer/drivers/MediaRenderer_vimeo.php: Es la clase que implementa el adaptador Vimeo.
  • application/controllers/Media.php: Es la clase controlador que vamos a implementar para demostrar el uso de nuestro controlador personalizado.

Así que esa es la lista de archivos que vamos a implementar a lo largo de este artículo.

Crea Controladores

En esta sección, vamos a crear los archivos base de nuestro controlador base.

Lo primero que tenemos que hacer es definir el archivo de configuración de nuestro controlador personalizado. Definamos el archivo application/config/mediarenderer.php como se muestra abajo.

1
<?php
2
$config['media_services'] = array('youtube', 'vimeo');
3
$config['media_default'] = 'youtube';

Este indica que vamos a implementar dos adaptadores---YouTube y Vimeo. El adaptador por defecto está establecido a YouTube.

Continúa y crea un archivo application/libraries/MediaRenderer/MediaRendererInterface.php con los siguientes contenidos.

1
<?php
2
defined('BASEPATH') OR exit('No direct script access allowed');
3
4
/**

5
 * MediaRendererInterface

6
 */
7
interface MediaRendererInterface
8
{
9
    public function display($id);
10
}

Como puedes ver, es una interfaz bastante básica que se asegura de que el adaptador que implementa esta interfaz debe implementar el método display.

Después, echemos un vistazo al archivo de controlador MediaRenderer. Continúa y crea un archivo application/libraries/MediaRenderer/MediaRenderer.php con los siguientes contenidos.

1
<?php
2
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
3
interface_exists('MediaRendererInterface', FALSE) OR require_once(APPPATH.'/libraries/MediaRenderer/MediaRendererInterface.php');
4
5
/**

6
 * MediaRenderer Class

7
 */
8
class MediaRenderer extends CI_Driver_Library {
9
    
10
  public $valid_drivers;
11
  public $CI;
12
  protected $_adapter = 'youtube';
13
14
  /**

15
   * Class constructor

16
   */
17
  public function __construct()
18
  {
19
    $this->CI =& get_instance();
20
    $this->CI->config->load('mediarenderer');
21
    $this->valid_drivers = $this->CI->config->item('media_services');
22
    $this->_adapter = $this->CI->config->item('media_default');
23
  }
24
25
  /**

26
   * Overrided __get method to check if the adapter implements MediaRendererInterface interface

27
   * @see CI_Driver_Library::__get()

28
   */
29
  public function __get($child)
30
  {
31
      if (in_array($child, $this->valid_drivers))
32
      {
33
          $object = $this->load_driver($child);
34
          
35
          if ($object instanceof MediaRendererInterface)
36
          {
37
              return $object;
38
          }
39
          else
40
          {
41
              show_error("MediaRenderer: Adapter '".$child."' doesn't implement MediaRendererInterface. Aborting.");
42
              return;
43
          }
44
      }
45
      else
46
      {
47
                show_error('Unable to load the requested adapter: '.$child);
48
                return;
49
      }
50
  }
51
52
  /**

53
   * @param string $adapter Adapter name

54
   * @return MediaRenderer

55
   */
56
  public function setAdapter($adapter)
57
  {
58
      $this->_adapter = $adapter;
59
      return $this;
60
  }
61
62
  /**

63
   * @param string $id Media ID

64
   */
65
  public function display($id)
66
  {
67
      return $this->{$this->_adapter}->display($id);
68
  }
69
70
}

Al inicio del archivo, incluimos la interfaz MediaRendererInterface que ya definimos antes en esta sección.

En cuanto a los estándares de controlador CodeIgniter, nuestra clase MediaRenderer extiende la clase CI_Driver_Library que asegura que podríamos acceder fácilmente adaptadores de controlador usando el método load_driver definido en la clase CI_Driver_Library.

Después, echemos un vistazo más cercano al constructor.

1
public function __construct()
2
{
3
  $this->CI =& get_instance();
4
  $this->CI->config->load('mediarenderer');
5
  $this->valid_drivers = $this->CI->config->item('media_services');
6
  $this->_adapter = $this->CI->config->item('media_default');
7
}

Recuerda el archivo de configuración mediarenderer que definimos anteriormente y que está exactamente cargado en el constructor en primer lugar. Es requerido que establezcas la lista de adaptadores que son soportados por el controlador a la propiedad valid_drivers, así que hicimos esto también. Y finalmente, hemos establecido el valor del controlador por defecto a la propiedad _adapter para nuestra conveniencia.

Continuando, pongamos el código del método __get.

1
public function __get($child)
2
{
3
    if (in_array($child, $this->valid_drivers))
4
    {
5
        $object = $this->load_driver($child);
6
        
7
        if ($object instanceof MediaRendererInterface)
8
        {
9
            return $object;
10
        }
11
        else
12
        {
13
            show_error("MediaRenderer: Adapter '".$child."' doesn't implement MediaRendererInterface. Aborting.");
14
            return;
15
        }
16
    }
17
    else
18
    {
19
            show_error('Unable to load the requested adapter: '.$child);
20
            return;
21
    }
22
}

Diría que no se requiere que anules este método, y nuestro controlador funcionará bien sin este también. La razón detrás de la implementación de este método en nuestro caso es reforzar la implementación de la interfaz MediaRendererInterface, y de ahí se asegurará de que cada controlador debe implementar el método display.

Después, echemos un vistazo al método setAdapter.

1
public function setAdapter($adapter)
2
{
3
    $this->_adapter = $adapter;
4
    return $this;
5
}

Como puedes ver, solo es usado para anular los ajustes de adaptador por defecto en caso de que quieras usar un adaptador diferente por cuestión de tiempo.

Finalmente, hay un método display que llama al método display del adaptador correspondiente.

1
public function display($id)
2
{
3
    return $this->{$this->_adapter}->display($id);
4
}

De nuevo, diría que puedes omitir la implementación del método display ya que siempre podrías llamar al método display del adaptador directamente, como veremos después en este artículo. Sin embargo, me gustaría acceder a los adaptadores vía el método display de la clase MediaRenderer ya que este es el lugar en donde podrías refactorizar el código común que el adaptador implementaría.

Así que esa fue la clase MediaRenderer a tu disposición.

Crea Adaptadores

Hemos estado discutiendo los adaptadores de controlador por un tiempo, y ahora es tiempo de realmente implementarlos.

Comencemos con el archivo adaptador YouTube en application/libraries/MediaRenderer/drivers/MediaRenderer_youtube.php.

1
<?php
2
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
3
4
/**

5
 * MediaRenderer_youtube Class

6
 */
7
class MediaRenderer_youtube extends CI_Driver implements MediaRendererInterface {
8
9
  /**

10
   * @param string $id Media ID

11
   * @see MediaRendererInterface::display()

12
   */
13
  public function display($id)
14
  {
15
    if ($id)
16
    {
17
      return '<iframe width="420" height="315" src="//www.youtube.com/embed/'.$id.'" frameborder="0"

18
allowfullscreen></iframe>';
19
    }
20
  }
21
22
}

Es importante notar que el nombre de adaptador está prefijado con MediaRenderer_, y también extiende a la clase CI_Driver. También, implementa la interfaz MediaRendererInterface para asegurar que adherimos a los estándares que discutimos anteriormente.

La razón de que nuestra clase adaptador extiende a la clase CI_Driver es aprovechar todos los métodos y propiedades padre. Has escuchado bien, puedes acceder métodos y propiedades de la clase MediaRenderer desde dentro de la clase MediaRenderer_youtube incluso aunque no extienda a la clase MediaRenderer directamente.

Aparte de eso, es bastante sencillo entender la implementación del método display, el cuál devuelve el código embebido siempre que el media ID sea pasado como un argumento del método.

La clase adaptador Vimeo es bastante idéntica a la de YouTube. Continúa y crea una en application/libraries/MediaRenderer/drivers/MediaRenderer_vimeo.php.

1
<?php
2
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
3
4
/**

5
 * MediaRenderer_vimeo Class

6
 */
7
class MediaRenderer_vimeo extends CI_Driver implements MediaRendererInterface {
8
    
9
    /**

10
     * @param string $id Media ID

11
     * @see MediaRendererInterface::display()

12
     */
13
  public function display($id)
14
  {
15
      if ($id)
16
      {
17
      return '<iframe width="420" height="247" src="//player.vimeo.com/video/'.$id.'"></iframe>';
18
      }
19
  }
20
21
}

Y eso concluye la discusión de adaptadores.

Juntándolo Todo

En el último par de secciones, hemos discutido las clases de controlador y adaptador. En esta sección, la cuál es la última de este artículo, extenderemos nuestro viaje para ir a través de una demostración de uso básico de controlador.

Comencemos creando un archivo controlador application/controllers/Media.php.

1
<?php
2
defined('BASEPATH') OR exit('No direct script access allowed');
3
4
/**

5
 * Media Controller Class

6
 */
7
class Media extends CI_Controller {
8
  public function index()
9
  {
10
    // this will use default adapter as per the config file

11
    $this->load->driver('mediaRenderer');
12
    
13
    // IMP: it must be a lowercase drivername when you use it

14
    echo $this->mediarenderer->display("0GfCP5CWHO0");
15
    
16
    // override adapter settings by setting it explicitly

17
    echo $this->mediarenderer->setAdapter('vimeo')->display("225434434");
18
    
19
    // access the adapter directly

20
    echo $this->mediarenderer->vimeo->display("225434434");
21
    echo $this->mediarenderer->youtube->display("0GfCP5CWHO0");
22
  }
23
}

Lo primero que necesitamos hacer es cargar nuestro controlador personalizado mediaRenderer, y eso es lo que el siguiente código hace.

1
$this->load->driver('mediaRenderer');

Para acceder al controlador personalizado que acabamos de cargar, deberías usar la sintaxis $this->mediarenderer. Es importante notar que el nombre del controlador está en minúsculas, desconsiderando el nombre real del controlador.

Después, examinemos lo que hace el siguiente código.

1
echo $this->mediarenderer->display("0GfCP5CWHO0");

Este llama al método display de la clase MediaRenderer en primer lugar, en donde delega el control al método display del adaptador correspondiente que está establecido por defecto en el archivo de configuración mediarenderer. Eventualmente, este termina llamando al método display del adaptador YouTube y ese es el adaptador por defecto en nuestro caso.

Por otro lado, si quieres llamar al método display de cualquier adaptador específico, siempre podrías hacer eso explícitamente como se muestra en el siguiente código.

1
echo $this->mediarenderer->setAdapter('vimeo')->display("225434434");

Como mencioné anteriormente, podrías también llamar al método display de cualquier adaptador específico directamente, sin ir a través del método display de la clase MediaRenderer.

1
echo $this->mediarenderer->vimeo->display("225434434");
2
echo $this->mediarenderer->youtube->display("0GfCP5CWHO0");

Así es como se supone que llames al controlador y sus adaptadores---gracias a la estructura del controlador que te permite enchufar los nuevos adaptadores sobre la marcha según sea necesario.

Y eso es todo. Espero que hayas disfrutado el artículo, y siempre podrías ir a la sección de comentarios para expresar tus ideas y dudas.

Conclusión

Un viaje a través de los controladores del marco de trabajo CodeIgniter fue la receta del artículo de hoy.

Como siempre, el artículo comenzó con una introducción básica al concepto de controladores en el marco de trabajo de CodeIgniter. Como prometí, entramos a crear un controlador personalizado basado en un caso de uso real, y esa creo yo es la mejor manera de entender un nuevo concepto.

¡Me encantaría escuchar si podrías idear algo sobre este emocionante concepto!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.