Utiliser plusieurs bases de données
lundi 20 août 2007 à 00:43 :: Prado :: #48 :: rss
Si vous utilisez comme moi les Active Records et que vient le jour où vous avez besoin d'accéder à plus d'une seule base de donnée dans votre application sous Prado, et bien ça peut être le début d'une longue nuit d'insomnie...
... et pourtant c'est si simple Ne cherchez plus, je vous donne[1] la solution !
Tout est écrit dans le Quikstart, il faut juste lire anglais et entre les lignes
Dans la page sur les ActiveRecords ils[2] proposent de créer les classes suivantes, une pour chaque connexion à une base de donnée (BDD) différente.
<?php class MyDb1Record extends TActiveRecord { public function getDbConnection() { static $conn; if($conn===null) $conn = new TDbConnection('xxx','yyy','zzz'); return $conn; } } class MyDb2Record extends TActiveRecord { public function getDbConnection() { static $conn; if($conn===null) $conn = new TDbConnection('aaa','bbb','ccc'); return $conn; } } ?>
Ils oublient juste de préciser ce qu'il faut en faire de ces classes ensuite. Même si ça parait évident, sauf quand on débute ou qu'on est passé de PHP4 à PHP5 sans apprendre vraiment la POO... ... bref j'éclaircis pour les esprits les plus lents
Et bien en fait c'est tout simple, et c'est une des "bases" de la POO : l'héritage, et c'est ce que je vous recommande chaudement de faire avec Prado, chaque fois que vous avez besoin de sortir des sentiers battus. N'oubliez pas que Prado est écris en PHP5 et que ce dernier nous permet enfin de faire de l'héritage digne de ce nom.
Supposons que nous ayons une table Login toute simple connectée à une base de donnée comme toutes nos autres tables, bref comme d'habitude :
<?php class LoginRecord extends TActiveRecord { const TABLE='Login'; public $idx; public $name; public $pass; public static function finder($className=__CLASS__) { return parent::finder($className); } } ?>
Et bien si l'on veut la connecter à une autre base de donnée il suffit de remplacer TActiveRecord par le nom de la classe réalisant la connexion, par exemple MyDb2Record. Ce qui nous donne à la place du code précédent :
<?php class LoginRecord extends MyDb2Record { # [...] } ?>
Seulement cette solution n'est pas des plus commode, car si comme moi vous utiliser le générateur de prado-cli pour obtenir à la volée vos classes à partir de votre BDD et bien vous allez être obligé de modifier à la main toute vos classes utilisant votre BDD par defaut. Donc, le plus simple est de garder une configuration par defaut pour l'ensemble des tables ayant besoin de la plus grosse BDD et d'appeller MyDb2Record pour les table de la plus petite BDD.
Vous aurez alors un fichier application.xml qui ressemblera à ceci du côté BDD :
[...] <modules> <module id="db" class="System.Data.TDataSourceConfig"> <database ConnectionString="mysql:host=localhost;dbname=xxx" Username="yyy" Password="zzz" /> </module> <module class="Application.Common.MTActiveRecordConfig" ConnectionID="db" /> [...]
Si vous vous posez des question au sujet du M au début de MTActiveRecordConfig allez lire mon article Bases de données MySQL en UTF-8.
Du coup vous n'êtes plus obligé de déclarer et d'utiliser MyDb1Record... enfin quoi que certains trouverons que c'est bancal d'utiliser une solution d'un côté et une autre de l'autre... je vous l'accorde, mais c'était surtout pour vous préparer à la suite
Car déclarer les paramètres de connexion dans les classes c'est franchement pas pratique, et le fichier application.xml est là pour ça non ? Donc, déclarons également la connexion à notre deuxième BDD dans le fichier application.xml :
[...] <modules> <module id="db1" class="System.Data.TDataSourceConfig"> <database ConnectionString="mysql:host=localhost;dbname=xxx" Username="yyy" Password="zzz" /> </module> <module id="db2" class="System.Data.TDataSourceConfig"> <database ConnectionString="mysql:host=localhost;dbname=aaa" Username="bbb" Password="ccc" /> </module> <!-- On garde tout de même une connexion par defaut... mais c'est à vous de choisir ! --> <module class="Application.Common.MTActiveRecordConfig" ConnectionID="db1" /> [...]
Seulement il faut du coup adapter les classes MyDb1Record et MyDb2Record en conséquence, je vous présente MyDb1Record et vous ferez de même avec MyDb2Record comme des grands
<?php class MyDb1Record extends TActiveRecord { public function getDbConnection(){ static $conn; if($conn===null) { $conn=PRADO::getApplication()->getModule('db1')->getDbConnection(); # pas obligatoire mais ça me rassure <img src="/dotclear/themes/Natsimhan/smilies/wink.png" alt=";-)" class="smiley" /> $conn->Active=true; # la petite commande permettant de paramétrer la discution avec la BDD en UTF-8 $command=$conn->createCommand("SET NAMES 'UTF8'"); $command->execute(); } return $conn; } } ?>
Et voilà, le tour est joué !!! Maintenant vous êtes capable de vous connecter à autant de BDD que vous les souhaitez depuis une seule et même application faite sous Prado
En supplément, voici quelques pages où j'ai trouvé de l'aide sur ce sujet :
Commentaires
1. Le vendredi 07 septembre 2007 à 19:45, par song75
Ajouter un commentaire
Les commentaires pour ce billet sont fermés.