Magazine High tech

Modèle et contrôleur avec CodeIgniter (partie 3)

Publié le 16 avril 2009 par Ekevin

Dans la partie précédente nous avons vu comment se servir de la base de données avec CodeIgniter, cependant nous n’avons pas réellement respecté la logique de séparation du MVC. C’est ce que nous allons faire dans ce tutoriel (enfin presque). Nous avons vu également comment déclarer une nouvelle action dans un contrôleur. Dans cette partie, nous allons créer notre premier modèle avec ses méthodes ainsi qu’un contrôleur. Nous ne verrons pas comment envoyer des données à la vue. Ceci, sera le sujet du prochain tutoriel.

Implementation d’un premier modèle

Un modèle dans une architecture MVC se charge de communiquer avec les données qui peuvent être dans une base de données, dans un fichier, sur un site extérieur, dans un flux RSS…
Notre premier modèle va se charger de correspondre avec notre base de données sous MySQL. Pour ceux venant du deuxième tutoriel nous n’altérerons que la table pour ajouter une ville et un pays.

Pour altérer une table sous PhpMyAdmin vous devez cliquer sur la base de données (tut_pasunclou) puis sur la table (Users) et vous devriez voir ceci :

Menu pour altérer une table sous PhpMyadmin

Menu pour altérer une table sous PhpMyadmin

Nous ajoutons donc 3 champs (city, country, colour) et des données dont vous trouverez les détails ci-dessous (n’oubliez pas d’effacer vos anciennes données ou de les adapter en conséquences).

Détail de la table :

CREATE TABLE Users (
  idUsers INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  username VARCHAR(45) NOT NULL,
  city VARCHAR(45) NOT NULL,
  country VARCHAR(45) NOT NULL,
  colours VARCHAR(45) NOT NULL,
  PRIMARY KEY(idUsers)
);

INSERT INTO Users (username, city, country, colours) VALUES ("Kevin", "Oxford", "Royaume-Uni", "vert");
INSERT INTO Users (username, city, country, colours) VALUES ("Raoul", "Paris", "France", "bleu");
INSERT INTO Users (username, city, country, colours) VALUES ("Esmeralda", "Santa Fe", "Argentine", "rouge");
INSERT INTO Users (username, city, country, colours) VALUES ("Nathalie", "Barcelone", "Espagne", "bleu");
INSERT INTO Users (username, city, country, colours) VALUES ("Naomie", "Lille", "France", "rouge");

Dans notre modèle, nous voulons pouvoir consulter, ajouter et mettre à jour des données. Nous allons implenter les méthodes suivantes :

  • getAll() : qui nous permettra de récupérer toutes les entrées
  • getByColour($colour) : nous pourrons sélectionner les données en filtrant par couleur
  • updateName($name) : mettra à jour la couleur d’un profil en indiquant le pseudo
  • Nous appellerons notre fichier users_model.php et nous le placerons dans le dossier application > models.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    class Users_model extends Model {
     
        public function __construct() {
            parent::Model();
            $data = array();
        }
     
        function getAll() {
            $query = $this->db->get('Users');
            $data = $query->result();
            $query->free_result();
            return $data;
        }
    }

    Cette classe est assez simple, en premier nous définissons un constructeur qui va hériter de la classe Model se situant dans le répertoire system > libraries.
    En second nous définissons une méthode qui se chargera de récupérer tous les articles de notre base de données grâce à la fonction $this->db->get('Users') ou articles est le nom de notre table (plus d’informations dans le fichier system > database > DB_active_rec.php et dans la documentation).

    Nous stockons alors le résultat dans une variable ($data) avant de libérer la mémoire associée à cette requête. Il n’est pas nécessaire de procéder à cette étape si vous vous contentez de quelques requêtes car PHP s’occupe de libérer cette mémoire pour vous. Cependant il est bon de démarrer avec de bonnes pratiques.

    Actuellement notre site ne fait pas grand chose si ce n’est récupérer une table dans une base de données. Passons maintenant au contrôleur de ce modèle qui se chargera de faire le médiateur entre le modèle est la vue.

    Le controlleur

    Le controlleur va se charger de récupérer les données du modèle et de les envoyer à la vue. Comme pour le modèle nous définissons une classe qui va étendre (extends) le controlleur de CI (application > controllers > users.php).

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    class Articles extends Controller {
     
        function __construct() {
            parent::Controller();
            $this->output->enable_profiler(TRUE);
        }
     
        function index() {
            $this->load->model('Users_model');
            $data = $this->Articles_model->getAll();
        }
    }

    Si vous avez lu le paragraphe ci-dessus à propos du contrôleur, vous remarquerez des similarités avec le modèle de tout à l’heure.

    Premièrement nous héritons du contrôleur de CI qui lui-même héritant de CI_Base (Base4.php ou Base5.php en fonction de votre version de PHP). Entre autre cet héritage permet d’avoir accès à toutes les classes instanciées dans le front contrôleur (system > codeigniter > CodeIgniter.php) comme config, input, benchmark… et permet si vous l’avez déclaré d’écrire dans un log que le Contrôleur a été initialisé.

    Deuxièmement, nous remarquons le nom de notre classe (le modèle users_model) dans la méthode index() ainsi que la méthode getAll(). La méthode index() va charger la classe Users_model, par l’intermédiaire de la ligne suivante :

    1
    
    $this->load->model('Users_model');

    Cet appel est une autre manière de créer une instance du modèle. Nous aurions pu l’instancier manuellement mais CodeIgniter fournit des méthodes pour appeler nos différentes classes. De la même façon nous pouvons charger une librairie, un plugin ou encore un helper en remplaçant model respectivement par library, plugin et helper (documentation sur le Loader).

    La méthode model se charge de vérifier si votre classe existe (ou vos classes, vous pouvez définir un tableau).

    Enfin nous récupérons par l’intermédiaire du modèle tous les résultats contenus dans notre table Users. Ce résultat est stocké dans $data.

    Nous ne mettrons pas en forme le résultat de cette requête, nous nous contenterons d’ajouter un var_dump($data) à la fin de notre méthode index().

    À ce niveau voici ce que donne notre programme en pointant le navigateur sur http://localhost/users.

    Apercu du var_dump et du profiler de CodeIgniter

    Apercu du var_dump et du profiler de CodeIgniter

    La méthode index est la première méthode qu’il faut définir dans un contrôleur. C’est la méthode par défaut. Ainsi quand nous demandons à notre navigateur d’afficher http://localhost/users nous appelons le contrôleur articles et la méthode index. En affichant http://localhost/users/index nous devrions avoir le même résultat.

    Avant de coder nos deux dernières méthodes, arrêtons-nous quelques instants sur cette ligne

    1
    
    $this->output->enable_profiler(TRUE);

    Vous avez sans doute remarqué que nous avons quelques informations en dessous de nos données affichées avec var_dump. C’est le résultat du profiler, il nous donne des informations basiques sur :

    • le fichier utilisé
    • le temps d’affichage
    • la consommation mémoire
    • GET et POST
    • et enfin la requête effectué sur la BDD

    Ces informations sont très utiles si le résultat affiché n’est pas celui escompté.

    Ci-dessous, voici le code à ajouter à notre modèle et à notre contrôleur pour permettre de consulter les données de notre table par couleur ainsi que de mettre à jour la couleur d’un utilisateur.

    Users_model.php

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
        public function getByColour($colour) {
            $query = $this->db->get_where('Users', array('colours' => $colour));
            $data = $query->result();
            $query->free_result();
            return $data;
        }
     
        public function updateName($name, $colour) {
            $data = array( 
              'colours' => $colour,
            );
            $this->db->update('Users', $data, array('username' => $name));
          }

    users.php

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
        public function couleur($colour = null) {
            // la couleur est-elle définie ? si non renvoie à index
            if ($colour == null)
            {
                $this->load->helper('url');
                redirect('/users/index');
            }
            $this->load->model('Users_model');
            $data = $this->Users_model->getByColour($colour);
            var_dump($data);
        }
     
        public function update($name = null, $colour= null) {
            // la couleur et le nom sont-ils définies ?
            if ($name == null || $colour == null)
            {
                $this->load->helper('url');
                redirect('users/index');
            }
            $this->load->model('Users_model');
            $data = $this->Users_model->updateName($name, $colour);
            var_dump($data);
        }

    Rien de bien compliqué jusque maintenant, il suffit de comprendre comment travailler avec Active Record dans CodeIgniter. Cependant, nous remarquerons que nous ne respectons plus un principe fondamental de la Programmation Orientée Objet. Le DRY (Don’t Repeat Yourself - Ne pas se répéter). Il nous faut donc re-factoriser.

    Il existe des multitudes de solutions pour se faire. Nous pourrions par exemple mettre le chargement du modèle Users_model dans le constructeur de la classe et y ajouter notre helper.

    Nous pourrions également créer de nouveaux helpers ou une librairie mais leurs usages ne conviennent pas vraiment dans notre cas.

    Nous pouvons aussi pour éviter d’avoir un fichier trop long, créer une nouvelle classe qui sera étendue par tous nos contrôleurs. Pour ma part, je préfère cette solution.

    Cette classe doit se situer dans le dossier application > libraries et doit se nommer MY_Controller.php (voir la doc)

    MY_Controller.php

    1
    2
    3
    4
    5
    6
    7
    8
    
    class MY_Controller extends Controller {
     
        public function __construct() {
            parent::Controller();
            $this->output->enable_profiler(true);
            $this->load->model('Users_model');                                          
        }
    }

    Voici la nouvelle version de notre contrôleur
    users.php

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    
    class Users extends MY_Controller {
     
        public function __construct() {
            parent::__construct();
        }
     
        public function index() {
            $data = $this->Users_model->getAll();
            var_dump($data);
        }
     
        public function couleur($colour = null) {
            // la couleur est-elle définie ? si non renvoie à index
            if ($colour == null) {
                $this->load->helper('url');
                redirect('/users/index');
            }
            $colour = strtolower($colour);
            $data = $this->Users_model->getByColour($colour);
            var_dump($data);
        }
     
        public function update($name = null, $colour= null) {
            // la couleur et le nom sont-ils définies ?
            if ($name == null || $colour == null) {
                $this->load->helper('url');
                redirect('users/index');
            }
            $data = $this->Users_model->updateName($name, $colour);
            var_dump($data);
        }
     
    }

    Nous pouvons enfin accéder à nos deux nouvelles fonctions en tapant http://localhost/users/couleur/bleu et http://localhost/users/update/kevin/violet

    Il ne nous reste plus qu’à envoyer nos données à notre vue pour avoir un résultat. Nous nous occuperons des templates dans la prochaine partie.


Retour à La Une de Logo Paperblog

A propos de l’auteur


Ekevin 5 partages Voir son profil
Voir son blog

l'auteur n'a pas encore renseigné son compte l'auteur n'a pas encore renseigné son compte