Bonnes pratiques sur la gestion de bases de données sous CodeIgniter
Je vous propose au travers de ce tutoriel de mettre en évidence 3 bonnes pratiques concernant la gestion de base de données sous CodeIgniter et plus particulièrement par rapport à la création de modèles basés sur la classe Active Record.
Je précise avant tout que les points évoqués ci-après sont pleinement compatibles avec ACICRUD, ma librairie d’abstraction de modèles pour CodeIgniter.
Gérer efficacement les préfixes de tables
Afin de débuter cet article, parlons des préfixes de tables pour vos applications. Puisqu’il est admit par le simple fait d’utiliser une librairie d’abstraction de base de données comme Active Record sous CodeIgniter, que votre base de données est abstraite, c’est à dire que l’on ne connaît pas en théorie quel système de gestion de base de données est utilisé en production, je considère également admit que vous ne devriez pas connaître la liste des tables présentes dans la base de données de production (ou du moins qu’il ne faut pas en tenir compte lors de la création du schéma de base de données de votre application).
Ainsi, afin d’éviter toute collision de table avec un autre système utilisant la même base de données, il devient très utile de préfixer l’ensemble des tables de notre application par une chaîne unique mais explicite.
Pour illustrer ceci, nous allons partir du principe que nous concevons une application nommée « Gestion » pour un client donné. Nous ne pouvons pas connaître à l’avance la liste des tables dans la base de données qu’utilise déjà notre client pour ses autres applications.
Aussi, afin d’éviter toute collision sur les noms de tables, nous allons choisir de préfixer nos tables avec la chaîne « gestion_ ».
C’est ainsi que toutes nos tables SQL devront être créées avec ce préfixe, comme par exemple « gestion_user », « gestion_user_acl », etc. De cette manière, si la base de données de production comporte déjà une table nommée « user », cela ne générera aucun conflit.
Ceci est très facilement gérable avec CodeIgniter, en effet il suffit d’indiquer le préfixe de table à utiliser dans le fichier de configuration database.php. Ainsi, Active Record utilisera automatiquement le préfixe de nos tables pour lors de la génération de requêtes SQL.
$db['production']['hostname'] = "localhost";
$db['production']['username'] = "root";
$db['production']['password'] = "password";
$db['production']['database'] = "the_production_database";
$db['production']['dbdriver'] = "mysql";
$db['production']['dbprefix'] = "gestion_";
$db['production']['pconnect'] = FALSE;
$db['production']['db_debug'] = FALSE;
$db['production']['cache_on'] = FALSE;
$db['production']['cachedir'] = "";
$db['production']['char_set'] = "utf8";
$db['production']['dbcollat'] = "utf8_general_ci";
Ne pas coder en dur les noms de table !
Voici une règle simple mais souvent oubliée : éviter de coder en dur. Ceci est particulièrement valable pour les noms de tables !
Voici comment profiter simplement de la programmation orientée objet afin de transformer notre nom de table en attribut de classe de notre modèle.
Ainsi, à chaque fois que nous aurons besoin d’appeler la table utilisée par le modèle, il suffira d’utiliser $this->table, ce qui aura également comme avantage de rendre les méthodes du modèle plus génériques.
Utiliser un préfixe de table avec la classe Database
Il existe certains cas de figures ou les méthodes évoquées ci-dessus ne suffisent pas totalement. C’est notamment le cas lorsqu’une requête SQL doit être effectuée sur plusieurs tables ou lorsque le query builder d’Active Record n’est plus utilisé.
Prenons un exemple concret en sélectionnant des données dans la table gestion_user via la méthode query(). Dans ce cas précis, le préfixe de table ne sera pas automatiquement ajouté par CodeIgniter puisque query() permet justement d’écrire manuellement une requête SQL.
Il faut alors utiliser $this->db->dbprefix() afin de générer le préfixe de table adéquat.
Notez que les deux méthodes produisent un résultat identique.
Conclusion
Il existe de nombreuses méthodes permettant d’améliorer la qualité et la généricité des modèles sous CodeIgniter, et nous n’abordons même pas les notions d’ORM ou de CRUD dans cet article. Quoiqu’il en soit, je suis sûr que chaque développeur CodeIgniter utilise ses propres techniques, aussi n’hésitez pas à partager les vôtres en commentant ce billet 😉
Salut,
Personnellement j’utilise des constantes, mais j’hésite à les faire devenir attribut.
D’un point de vue « sémantique », le nom des tables devraient être des constantes (puisque les noms sont sensés être constants :p). Honnêtement, l’utilisation des constantes est vraiment barbant: Utilisateur_model::TABLE_NAME c’est un peu long à écrire (même avec l’auto-complétion d’eclipse ;D) et ça complexifie le code pour pas grand chose.
Je pense explorer une autre technique, similaire à la tienne. Cela consisterait à créer un MY_Model qui ne contiendrait que l’attribut table (ainsi qu’un getter de l’attribut et une méthode qui retournerait « $this->db->dbprefix().$this->getTableName() »). Bien sûr, les modèles hériteraient de MY_Model et non plus de Model directement.
C’est ce que tu fais, mais avec une niveau d’abstraction supplémentaire pour « simplifier » et surtout normaliser au maximum l’écriture des requêtes SQL (dans mon cas, nous sommes plusieurs à développer et certains oublieraient de mettre le prefix, je le sais ^^).
Qu’en penses-tu ?
Bonjour, personnellement je ne suis pas fan des constantes, en POO il est facile d’obtenir le même résultat sans avoir à les utiliser.
La solution de dériver une classe héritant de Model est bonne car d’une part elle permet de factoriser le $this->table, mais elle permet également de gagner en généricité.
C’est exactement la méthodologie employée dans ma librairie Acicrud. En effet, tous les modèles héritent d’Acicrud au lieu de Model, il peuvent ainsi non seulement définir leur table une seule et unique fois, mais il peuvent également bénéficier de tout un tas de méthodes ainsi que d’un CRUD.
est ce que c’est possible d’utiliser un préfixe manuellement sans le faire appel dans config db car il existe des cas ou je veux pas utiliser le prefixe !!!