Usando ‘Hooks’ en CodeIgniter
Muchas veces nos encontraremos, al programar nuestras aplicaciones, que necesitamos realizar una tarea en todas las paginas por igual, en un mismo momento. Hay una solución para eso, muy muy mala, que es hacer un copy&paste del código en todas las paginas (si.. si.. quien no ha hecho eso alguna vez…).
Por suerte CodeIgniter nos trae de la mano una buena herramienta llamada ‘Hooks’ o ganchos, que simplemente nos permite hacer eso, ejecutar determinadas funciones en un determinado momento.
El “determinado momento”, básicamente puede ser:
- pre_system: al principio de la ejecución del sistema, sin haber cargado básicamente nada.
- pre_controller: ejecutar antes de cargar el controlador, una vez cargadas las librerías y todo el systema básico.
- post_controller_constructor: justo se ejecutar tras el constructor del controlador pero antes de cualquier función.
- post_controller: se ejecutará una vez lo haya hecho el controlador.
- display_override: esto es para sobrescribir la función que nos muestra la pagina finalizada en el navegador.
- cache_override: lo mismo pero para la función de cache, nos permite sobreescrivirla.
- scaffolding_override: para crear nuestro propio scaffolding.
- post_system: ejecutará el código al final de todos los procedimientos.
En la user_guide de Codeigniter podréis encontrar esta información más extendida.
Bien, para que quede más claro, vamos a ver un ejemplo. En este caso supondremos que estamos trabajando en una página web multilenguaje. Y queremos crear un ‘hook’ que nos lea una variable de sesión que contiene el idioma que hay seleccionada y con eso nos cargue el idioma especificado (para los que no sepáis como funciona la “language class”, echarle un vistazo en la guía).
Antes de empezar, necesitaremos activar los hooks en el config.php:
$config['enable_hooks'] = TRUE;
Luego, accedemos al archivo “config/hooks.php”, y ahí definiremos nuestro hook y sus propiedades.
/*
| -------------------------------------------------------------------------
| Hooks
| -------------------------------------------------------------------------
| This file lets you define "hooks" to extend CI without hacking the core
| files. Please see the user guide for info:
|
| http://codeigniter.com/user_guide/general/hooks.html
|
*/
$hook['post_controller_constructor'] = array(
'class' => 'Estado',
'function' => 'idiomas',
'filename' => 'estado.php',
'filepath' => 'hooks'
);
/* End of file hooks.php */
/* Location: ./system/application/config/hooks.php */
En este caso podemos observar como usamos el evento “post_controller_constructor”, de manera que nos cargará justo después del constructor pero antes de cualquier función, por lo que será perfecto para definir en que idioma tenemos que trabajar.
Class: nos define que clase tenemos que cargar. Como veréis en el código mas adelante, vamos a cargar una clase que se llama Estado.
Function: como se llama la función que vamos a cargar, que por supuesto estará dentro de nuestra clase especificada.
Filename: en que archivo se encuentran la clase y la función especificada anteriormente? Ese archivo deberá ir colocado en “application/hooks”, en nuestro caso es “estado.php”.
Filepath: aquí definimos en que carpeta se encuentra nuestro archivo. Por defecto mira en la carpeta “hooks”, aunque podéis cambiar esto por “controllers” o algo así, aunque yo os recomiendo mantenerlo en “hooks” para tenerlo mas ordenado.
Una vez tenemos esto, procedemos a crear nuestro código
if(!defined('BASEPATH'))
exit('No direct script access allowed');
class Estado
{
function idiomas()
{
$CI =& get_instance();
$lang = $CI->session->userdata('idioma');
if(empty($lang))
{
$lang = "spanish";
$CI->session->set_userdata(array('idioma'=>'spanish'));
}
$CI->lang->load('global', $lang);
}
}
Como podéis ver, este código es muy simple. Recogemos el valor de una variable ’session’, hacemos una comprobación por si no existe y creamos una por defecto, luego cargamos el idioma según esa variable.
Bueno espero que con el ejemplo haya quedado claro, seguro que le encontráis muchas funcionalidades, la verdad es que son muy útiles.

Que buen post lagarto!
Los hooks es algo que yo por lo general no le prestaba mucha atencion, pero veo que son muy utiles, sobre todo para cargar cosas antes de ejecutar una pagina.
Gracias por este buen tuto :)
Esto lo he usando alguna vez en CakePHP, aunque se crean de otra manera.
Yo pensaba que los hooks eran para otra cosa y no los había mirado siquiera :D
Si, en CakePHP es igual pero simplemente escribes unas funciones en el controlador y se ejecutan en determinado momento.
Utilizando ‘post_controller_constructor’ logro cargar el lenguaje a usar despues que cargue el controlador principal, verdad? y si quiero cargar algunas traducciones por defecto utilizando autoload.php? seria mejor usar ‘pre_controller’ entonces?
Como puedo hacer?
Intenté montar el ejemplo y se carga bien el “post_controller_constructor”,,, se carga la “class”,, ejecuta la “function”.. imprimí la variable de sesión “idioma” y lo hace bien pero el problema es a la hora de cargar $CI->lang->load(‘global’, $lang);… aparentemente lo hace,,, pero el idioma sigue igual en el sitio… AYUDA!!
Muy buen post, claro y explicación simple.
Un saludo.
En principio felicitarte por el POST. Hace poco que he empezado a trabajar con CI y realmente me he enganchado.
Se me presenta el siguiente caso:
Tengo una web que usa dos idiomas (el castellano y el gallego).
Las url en castellano sería http://www.ejemplo.com/ES/tablon-de-anuncios y la url en gallego http://www.ejemplo.com/GL/taboeiro-de-anuncios.
- El que coja un idioma u otro según el prefijo en la URI no es problema.
- Si el controlador principal es tablon-de-anuncios.php como hago para al poner en la uri taboeiro-de-anuncios coja el controlador tablon-de-anuncios.php ¿se tendría que usar un hooks pre-controller, que llamase a una matriz que tradujese la uri? ¿Pero cómo se cambia de controlador? ¿hay alguna manera más simple dentro de cada controlador?
Es resumen, necesito que la uri cambie según el idioma pero que llame al mismo controlador (que podría ser dashborad.php posteriormente este usaria los mismos modelos,vistas y cargaría el archivo de idioma)