Herencia entre controladores en CodeIgniter

Publicado: 22/01/2010 en CodeIgniter, desarrollo, herencia, inherit, php
Etiquetas:, , , ,

You can read the English version of this post in http://phpsblog.agustinvillalba.com/inheritance-between-controllers-codeigniter/

Hoy vamos a hablar sobre la herencia entre controladores en CodeIgniter. A primera vista puede parecer que es muy sencillo y que no debería ser más complicado que hacer lo siguiente:

class Controlador_padre extends Controller {

function Controlador_padre()
{
parent::Controller();
...
}
...
}

class Controlador_hijo extends Controlador_padre {
function Controlador_hijo()
{
parent::Controlador_padre();
..
}
..
}


Si escribimos este código tal cual, el CodeIgniter nos devolverá un error diciendo que no puede encontrar la clase Controlador_padre, lo cual me resultó bastante soprendente. Para que el controlador que hereda pueda utilizar los métodos de su controlador padre y así hacer efectiva la herencia tenemos dos formas de hacerlo:

Método 1

Podemos hacerlo de la forma tradicional de PHP, es decir, invocando explícitamente los archivos dónde se encuentran las clases padre de la clase heredera. Por lo tanto, en el archivo controlador_hijo.php hemos de incluir el siguiente código:

require_once APPPATH.'controllers/controlador_padre.php';
class Controlador_hijo extends Controlador_padre {
...
}

Este método es perfectamente válido y funcionará sin ningún problema. De hecho, si el servidor en el que se va a ejecutar nuestro código es la versión 4 de PHP, ésta es la única forma que tenemos de hacer esto. Dado que hoy en día es bastante raro que aún se utilice PHP 4 en un servidor web, esta forma no me parece la más elegante ni la más comoda, dado que tenemos que replicar bastante código escribiendo todos los “requires” en cada uno de los controladores dónde queremos realizar la herencia. Si estamos programando para PHP 5, la mejor opción es utilizar la función __autoload(). Así que ésta la que utilizaremos.

Método 2: la función __autoload()

Como bien dijimos antes esta función es una de las tantas ventajas de PHP 5 sobre sus versiones anteriores. Para poder evitarnos el engorroso trabajo de tener que invocar todos y cada uno de los archivos de clase de los cuales hereda otra, podemos definirnos nuestra función __autoload() y así será el sistema el que se encargue automáticamente de comprobar si un archivo no ha sido inlcuido aún, en cuyo caso ella misma lo agrega al espacio de nombres. Llamando a esta función se le da una última oportunidad al sistema de incluir un archivo de clase antes de lanzar el error.

Es importante destacar que esta función nos será útil siempre y cuando ambos controladores, padre e hijo, se encuentren en el mismo directorio. Si nuestra estructura es del tipo controllers/padre.php y controllers/subfolder/hijo.php, entonces este método no nos será válido.

Para utilizar esta función en CodeIgniter tan sólo tenemos que incluir el siguiente código al final de nuestro archivo de configuración system/application/config/config.php:

function __autoload($class)
{
 if (file_exists(APPPATH."controllers/".$class.EXT))
 {
 require_once(APPPATH.'controllers/'.$class.EXT);
 }
}

De esta forma PHP se encargará de llamar a esta función antes de lanzar un error por no encontrar el archivo de clase que necesita para poder llevar a cabo la herencia. Con esto podemos tenemos lista la herencia entre clases en CodeIgniter con todos los niveles que nos sean necesarios.

You can read the English version of this post in http://phpsblog.agustinvillalba.com/inheritance-between-controllers-codeigniter/

Anuncios
comentarios
  1. Nichole dice:

    hum… muito bom ! 🙂

  2. luis dice:

    Dios te bendiga

  3. elias dice:

    me sirvio mucho 🙂

  4. geomorillo dice:

    tienes razon todo depende del proyecto

  5. geomorillo dice:

    mmm pues te cuento que puede funcionar sin el include y sin la funcion autoload,
    como ves se crea una clase en la carpeta libraries que son cargados automaticamente por codeigniter

    ./application/libraries/MY_Controller.php
    class MY_Controller extends Controller
    {
    function __construct()
    {
    parent::Controller();

    $this->load->helper(‘html’);
    }

    function fred($title=’Jack’)
    {
    echo heading($title);
    }

    }//endclass

    ./application/controllers/ci_first.php
    class ci_first extends MY_Controller
    {
    function __construct()
    {
    parent::Controller();
    }

    function index
    {
    $this->fred();

    $this->fred(‘jack’);

    $this->fred(‘harry’);

    }

    }//endclass

    ./application/controllers/ci_second.php
    class ci_second extends MY_Controller
    {
    function __construct()
    {
    parent::Controller();
    }

    function index
    {
    $this->fred();

    $this->fred(‘jack’);

    $this->fred(‘harry’);

    }

    }//endclass

    • Hombre… puede ser una alternativa. Lo que pasa que en este caso ya no podrás utilizar estas clases como controladores sino como libraries. Si el problema a solucionar te permite sacrificar los controllers por libraries es una solución totalmente válida, claro que sí, pero si estás obligado (por las razones que sea) a utilizar las clases heredadas como controllers también (por aquello de la url, las rutas y demás) pues no te queda más remedio que hacerlo como comentamos en el artículo. De todos modos una buena aportación! Muchas gracias.

      • octavio dice:

        no es tan asi, tienes todo lo atributos de tu controlador dejandolo en la carpeta libraries 😀

        • Sin duda es posible tener todos los atributos del controlador colocándolo en el directorio libraries, la cuestión es si eso es realmente interesante o no. Al colocar nuestro controlador en la carpeta libraries ya deja de ser un controlador y no podremos utilizarlo como tal en nuestro proyecto. Como coméntabamos más arriba, todo depende de si eso es interesante para el proyecto o no. Yo creo que lo mejor es colocar los controladores en la carpeta controllers y hacer la herencia entre ellos, en lugar de hacer el “truco” de colocar un controller en la carpeta libraries.

  6. Buenísimo el post como siempre. Muy útil 😉

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s