jeudi 23 février 2012

codeigniter

Etendre CodeIgniter : MY_Controller

Pour avoir un aperçu rapide de l’utilité de disposer d’un contrôleur « maître », voici un exemple simple :

Vous souhaitez utiliser la fonctionnalité de CodeIgniter qui vous permet d’utiliser le profileur sur un rendu html. la première approche consiste à intégrer l’appel à la fonction dans la méthode du contrôleur.

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class Home extends CI_Controller {

    public function index() {
        $this->output->enable_profiler(TRUE);
        $this->load->view('home');
    }

}

/* End of file home.php */
/* Location: ./application/controllers/home.php */

Cette solution fonctionne bien, c’est comme cela qu’il faut l’utiliser. Vous souhaitez utiliser le profileur sur chaque méthode de votre contrôleur. Pas de problème, il suffit d’ajouter un appel sur chaque méthode comme ceci :

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class Home extends CI_Controller {

    public function index() {
        $this->output->enable_profiler(TRUE);
        $this->load->view('home');
    }

    public function login() {
        $this->output->enable_profiler(TRUE);
        $this->load->view('login');
    }

}

/* End of file home.php */
/* Location: ./application/controllers/home.php */

A l’usage vous conviendrez de deux choses avec moi :

  1. C’est pas très maintenable,
  2. C’est pas très souple.

Nous allons donc factoriser un peu cela dans le constructeur :

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class Home extends CI_Controller {

    public function __construct() {
        parent::__construct();
        $this->output->enable_profiler(TRUE);
    }

    public function index() {
        $this->load->view('home');
    }

    public function login() {
        $this->load->view('login');
    }

}

/* End of file home.php */
/* Location: ./application/controllers/home.php */

Voilà toutes les méthodes sont profilées à la demande. Je vais juste déporter la valeur de enable_profiler() vers une variable globale comme cela je peux changer une variable et hop, toutes mes méthodes à profiler le sont (ou pas). Dans un fichier application.php dans le répertoire /application/config/ de votre installation Codeigniter :

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

$config['debug_profiler'] = FALSE;

/* End of file config.php */
/* Location: ./application/config/config.php */

Voilà qui est mieux, le nouveau code de votre contrôleur doit désormais prendre en compte le fichier de configuration :

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class Home extends CI_Controller {

    public function __construct() {
        parent::__construct();
        $this->config->load('application');
        $this->output->enable_profiler(config_item('debug_profiler'));
    }

    public function index() {
        $this->load->view('home');
    }

    public function login() {
        $this->load->view('login');
    }

}

/* End of file home.php */
/* Location: ./application/controllers/home.php */

C’est très bien, tout est en place, je charge mon fichier et dans chaque méthode, le profilage est en place. Le problème apparait lorsque je veux ajouter un contrôleur, je rajoute mon code dans chaque constructeur de chaque contrôleur. parmi les concepts que je tente de suivre dans mes développements (et que je vous invite à suivre) il y’a le principe « Don’t Repeat Yourself » (DRY – Ne répétez pas vous même) et c’est précisément ce que vous allez faire. Nous allons donc étendre le contrôleur de CodeIgniter afin d’y intercaler notre code. Créez un fichier MY_Controller (le MY_ dépendant de votre préfixe personnalisé) dans le répertoire /application/core/ de votre installation CodeIgniter. Ajoutez le code suivant :

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class MY_Controller extends CI_Controller {

    public function __construct() {
        parent::__construct();
        $this->config->load('application');
        $this->output->enable_profiler(config_item('debug_profiler'));
    }

}

/* End of file MY_Controller.php */
/* Location: ./application/controllers/MY_Controller.php */

Le nouveau code de notre contrôleur qui étend désormais MY_Controller:

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class Home extends MY_Controller {

    public function index() {
        $this->load->view('home');
    }

    public function login() {
        $this->load->view('login');
    }

}

/* End of file home.php */
/* Location: ./application/controllers/home.php */

Voilà c’est tout, maintenant toute votre application dispose du profiler à la demande juste en modifiant la valeur de debug_profiler dans le fichier de configuration. Un autre concept que respecte quasi systematiquement c’est « Convention over Configuration » (CoC – Convention plutôt que configuration). On traduit souvent cela par le codage par exception. Petite explication : la convention veut que chaque méthode de chaque contrôleur utilise le profileur (en fonction de mes préférences). Mais si je veux forcer une méthode à afficher ou non le profileur, je code une exception dans la méthode en question sans changer la mécanique par défaut :

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class Home extends MY_Controller {

    public function index() {
        $this->output->enable_profiler(TRUE);
        $this->load->view('home');
    }

    public function login() {
        $this->load->view('login');
    }

}

/* End of file home.php */
/* Location: ./application/controllers/home.php */

Voilà ce n’est qu’un modeste exemple de ce qu’il est possible de faire avec un contrôleur principal. Dans un billet précédent, il était question de forcer le https, vous pouvez utiliser ce helper pour forcer le https sur la partie administration de votre site par exemple comme ceci :

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class MY_Controller extends CI_Controller {

    public function __construct() {
        parent::__construct();
        // Simple test sur l'adresse (ex: ludal.fr/administration)
        if ($this->uri->segment(1) === 'administration') {
            $this->load->helper('url');
            force_ssl();
        }
    }

}

/* End of file MY_Controller.php */
/* Location: ./application/controllers/MY_Controller.php */

Comme vous le voyez, je ne gère plus du tout le ssl dans les autres contrôleurs, tout est centralisé. Vous pouvez poser toutes les questions que vous souhaitez pour éclaircir les passages qui ont pu vous échapper.

Télécharger le code source

À propos de l'auteur

Passionné d'informatique en général et de logiciel libre en particulier. Développeur sur de multiples langage & IDE (Delphi, .net, Java, PHP...). Administrateur de la communauté francophone de la distribution LinuxMint. Amoureux du développement sur CodeIgniter et à la recherche d'un associé (graphiste de préférence) pour monter un Business Model :-)

Autres articles par Ludal »

3 commentaires

  • Ludal | 24 janvier 2012 à 13 h 29 min | Répondre

    On peut étendre quasiment tout dans Codeigniter, c’est ce qui en fait sa force. Je vais essayer de vous pondre des billets sur les différentes classes dont je me sert, cela peut aider quelques uns d’entre vous.

Rétroliens pour cet article

Laisser un commentaire

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="">

Envoyer le commentaire »

Propulsé par WordPress