Accès aux données
- Acceder aux données à partir d'une méthode d'action
- Créer un nouveau module d'accès aux données
- Modules de données et agrégation de méthodes
- Utiliser d'autres SGBD
Acceder aux données à partir d'une méthode d'action
Dans une méthode d'action, la classe mw_controller fourni un accesseur env() qui retourne l'instance qui représente l'environnement d'éxecution, dans un objet env.
Cet un objet env fourni entre autres une méthode data() qu'on va pouvoir utiliser pour obtenir un accès aux données :
$env = $this->env();
$data = $env->data();
L'objet data ainsi obtenu propose alors des méthodes pour lire, modifier ou ajouter des données. Par exemple la méthode users() retourne la liste des utilisateurs enregistrés sur le site, dans un tableau associatif :
$env = $this->env();
$data = $env->data();
$users = $data->users();
Créer un nouveau module d'accès aux données
Les modules d'accès aux données se trouvent dans le répertoire :
app/data/modules
Si mtweb utilise le stockage de données dans des fichiers XML, les modules d'accès aux données sont chargés à partir du dossier xml. Si mtweb est configuré pour utiliser un SGBD SQL (MySql ou SQLite), les modules sont lus dans le dossier sql. Le dossier share contient des méthodes communes aux deux systèmes.
Imaginons maintenant que l'on ai créé une nouvelle table dans la base de données et que l'on souhaite pouvoir, dans une méthode d'action, lister le contenu de cette table via une nouvelle méthode :
$env = $this->env();
$data = $env->data();
$mon_listing = $data->mon_listing();
Pour cet exemple, on va se baser sur le stockage des données SQL et développer une fonction de listing pour une table mw_ma_table.
Notre module de données va se trouver dans le dossier :
app/data/modules/sql
Commençons par créer une nouvelle classe, dans un fichier :
app/data/modules/sql/mon_module.php
Avec ce code :
<?php
class mon_module extends mw_data{
function mon_listing(){
$sgbd = $this->sgbd();
$listing = array();
try{
$rst = $sgbd->query("SELECT * FROM #--ma_table");
while($v_rst = $sgbd->fetch_assoc($rst)) $listing[] = $v_rst;
$sgbd->free_result($rst);
}
catch(Exception $e) { $listing = false; }
return $listing;
}
}
?>
Le nom de la classe est au choix, à la seule condition qu'elle doit se trouver, dans le dossier des modules, dans un fichier qui porte son nom, avec une extention php. Pour un module de données SQL, la classe doit se trouver dans un fichier :
app/data/modules/sql/<nom_de_classe>.php
Cette classe doit hériter de mw_data.
Pour la méthode mon_listing, choisissez le nom et les paramètre d'appel que vous voulez. Attention tout de même au nom. Même s'il s'agit d'une méthode de classe, choisissez un nom de méthode unique parmis les méthodes définies dans l'ensemble des modules de données. On verra plus loin pourquoi.
Dans cet exemple, la méthode commence par récupérer un objet sgbd :
$sgbd = $this->sgbd();
C'est l'héritage de la classe mw_data qui fourni cette méthode, qui retourne un objet qui donne accès aux fonctions de base du SGBD. Ici, nous utilisons SQL et l'objet sgbd donne accès aux méthodes :
$sgbd->select_db($db_name)
selectionne la base de données
$sgbd->table_exists($table_name)
retoune TRUE ou FALSE selon si la table existe ou pas
$sgbd->query($query_string)
retourne un pointeur de résultats ou un bouléen
$sgbd->insert_id()
retourne l'identifiant ajouté après une insertion
$sgbd->fetch_assoc($rst)
retourne le résultat suivant dans un tableau associatif
ou FALSE quand il n'y plus de résultat
$sgbd->free_result($rst)
libère le pointeur de résultats
Toutes ces méthodes émettent une Exception Php en cas d'erreur, d'où l'utilisation d'un bloc try / catch dans notre méthode de listing.
Toujours concernant la gestion des erreurs, notre méthode mon_listing va remplir un tableau associatif avec les résulats et le retourner, ou retourner FALSE si une erreur survient, ce qui permettra de detecter l'erreur au niveau de la méthode d'action, en comparant la valeur de retour à FALSE.
note : s'il n'y a aucun enregistrement dans notre table, notre méthode de listing va retourner un tableau associatif vide, qui est équivalent à FALSE. Pour vérifier qu'il n'y a pas eu d'erreur lors de l'appel à cette méthode, il faudra utiliser la comparaison stricte ( !== FALSE ).
Une dernière remarque sur cet exemple, au sujet de la syntaxe SQL :
$rst = $sgbd->query("SELECT * FROM #--ma_table");
Les noms des tables de la base de données, dans mtweb, sont prefixées par défaut par mw_ mais vous pouvez changer ce préfix, dans le fichier config.php :
$bdd["table_prefix"] = "mw_";
Vous pouvez indiquer une chaine vide pour ne pas utiliser de prefixe.
Au moment de l'appel à la méthode sgbd->query(...), la chaine "#--" sera remplacée par le préfixe indiqué dans la configuration.
Modules de données et agrégation de méthodes
Lorsque mtweb charge les modules d'accès aux données, il agrège les méthodes des classes qu'il trouve, pour les regrouper dans un unique objet data. Une fois notre nouveau module de données enregistré, sa méthode mon_listing devient accessible dans une méthode d'action, via cet objet data :
$env = $this->env();
$data = $env->data();
$listing = $data->mon_listing();
De la même façon, si vous développez d'autres modules de données, dans d'autres fichiers, il seront définis dans des classes différentes, mais leurs méthodes seront directement accessible via l'objet data.
Il faut donc faire attention, dans les modules de données, à donner des noms de méthodes uniques, même si elle sont définies dans des classe différentes. Si deux méthodes portent le même nom dans deux modules différents, c'est la première trouvée qui sera utilisée.
Utiliser d'autres SGBD
On pourrait par exemple vouloir utiliser Postgresql, et développer des requêtes SQL compatibles avec Mysql pour avoir le choix du SGBD. Dans ce cas, que ce soit l'un ou l'autre, les requêtes sont en SQL et développées dans les mêmes méthodes, celles des classes du dossier sql, dans les modules de données :
app/data/modules/sql
Les drivers pour accéder aux SGBD sont par contre différents. Dans mtweb les fonctions d'accès aux SGBD (les fonctions de bases de type connect, select_db, query, ...) sont implémentées à part, dans les fichiers du dossier :
app/data/impl
Pour ajouter un support pour Postgresql, il faudrait ajouter un fichier d'implémentation dans ce dossier. Par exemple :
app/data/impl/mw_postgresql.php
Pour une bonne compatibilité avec Mysql, la classe devrait au moins définir les mêmes méthodes que celles définies dans le fichier :
app/impl/mw_mysql.php
Le nom du fichier d'implémentation doit s'appeler mw_<nom_sgbd>.php. C'est ensuite ce <nom_sgbd> que vous pourrez indiquer dans le fichier config.php :
$bdd["sgbd"] = "postgresql"; // fichier d'implementation : app/data/impl/mw_postgresql.php
Le fichier d'implémentation doit définir une classe mv_<nom_sgbd>, avec au minimum ceux deux particularités :
- son constructeur doit accepter 4 paramètres : le nom de l'hote, le nom de la base, le nom d'utilisateur de connexion et son mot de passe (dans cet ordre).
- elle doit aussi implémenter une méthode extention_ok(&$env) qui retourne TRUE ou FALSE selon si le SGBD est supporté ou pas.