Environnement base de données

Présentation de l'environnement



PHPBoost dispose d'une classe qui gère tout ce qui concerne les liaisons avec la base de données. Cela lui permet entre autres de pourvoir supporter plusieurs systèmes des gestion de base de données différents (MySQL est le plus souvent utilisé, mais on peut passer sous SQLite ou d'autres systèmes).

L'avantage de l'utilisation d'une classe est de simplifier les requêtes dans la base de données mais cela permet aussi par exemple de compter les requêtes. Des outils supplémentaires sont à votre disposition, comme par exemple la sauvegarde et la restauration de la base de données.

L'inconvénient de supporter plusieurs systèmes de gestion de base de données (SGBD) est au niveau de la syntaxe des requêtes. Tous les SGBD utilisent le langage SQL certes, mais certains comme MySQL permettent des syntaxes un peu différentes. Le problème est que MySQL étant le plus connu, tout le monde ou presque apprend à développer selon sa syntaxe et celle-ci n'est pas compatible avec les autres SGBD. Il va donc falloir s'adapter et utiliser une syntaxe qui respecte la norme SQL, qui elle est compatible avec tous les SGBD. Nous allons voir dans le paragraphe suivant ce à quoi nous devons faire attention.

Syntaxe à adopter



L'utilisation de différents SGBD nous contraint à utiliser une syntaxe légèrement différente de celle que de nombreux développeurs ont apprise pour MySQL. Rassurez-vous pour s'aligner avec la norme SQL il faudra seulement se préoccuper de quelques détails que nous allons voir ici.

Utilisation des guillemets



Sous MySQL il est possible d'utiliser les guillemets simples comme les guillemets doubles lorsqu'on envoie des chaines de caractères dans les requêtes. Mais pour que les requêtes soient compatibles avec tous les SGBD, il va falloir utiliser uniquement les guillemets simples. Ainsi la requête suivante n'est pas correcte.
Code :
SELECT * FROM table WHERE pseudo = "surnom"

Elle est à remplacer par la requête suivante.
Code :
SELECT * FROM table WHERE pseudo = 'surnom'

Ainsi vos requêtes devront être placées entre guillemets doubles, en voici un exemple.
Code :
<?php
$requete 
"SELECT * FROM table WHERE pseudo = '" $pseudo "'"
?>

Il est très important de respecter ces quelques règle élémentaires sans quoi vos requêtes devront toutes être reprises. Inutile donc de vous dire qu'il est fortement conseillé de commencer à coder comme ceci, vous n'aurez pas de travail supplémentaire pour adapter votre syntaxe.

Limit



Chaque SGBD n'utilise pas la syntaxe LIMIT debut, nombre pour déterminer le nombre de lignes retournées. Ainsi la requête suivante n'est pas correcte.
Code :
<?php
$requete 
"SELECT * FROM table LIMIT 0, 10"
?>

Elle est à remplacer par la requête suivante:
Code :
<?php
$requete 
"SELECT * FROM table " $sql->sql_limit(010); 
?>

La classe $sql est appelée en fonction du SGBD utilisé et elle contient donc directement les bonnes syntaxes et fonctions, vous n'aurez pas à vous en préoccuper.

Nom des tables



Pour autoriser l'installation multiple de PHPBoost sur une même base de données les tables sont préfixées afin de pouvoir les distinguer. Il faudra donc prendre en compte cette considération dans la création de votre module. Le préfixe choisi par l'utilisateur est contenu dans la constante PREFIX, vous verrez par la suite des exemples d'utilisation.

Requêtes de sélection



L'environnement SQL de PHPBoost permet de faire des requêtes dans la base de données de façon simple.
Bien que cet environnent soit basé sur de la programmation orientée objet, aucune connaissance particulière en programmation objet n'est nécessaire puisque vous devrez systématiquement copier les exemple fournis ici.

Requêtes simples sur un seul champ



Voyons par exemple comment faire des requêtes de sélection sur un seul champ dans une seule table et sur une seule ligne (boucle impossible).
Code :
<?php
$var 
$sql->query("SELECT champ FROM ".PREFIX."table WHERE pseudo = '" $pseudo "'"__LINE____FILE__);
?>

Quelques précisions :


Requêtes multiples : champs d'une même table



Nous allons voir ici comment sélectionner des champs d'une même table. Ce type de requête est limité car il ne permet de retourner qu'une ligne. Nous allons voir un exemple ici.
Code :
<?php
$var 
$sql->query_array("table""champ1""champ2", ..., "champn""WHERE condition"__LINE____FILE__); 
echo 
$var['champ3']; //Affichage du champ 'champ3'
?>

Précisions :


Requêtes complexes ou en boucle



Venons-en maintenant aux requêtes plus complexes qui sont en pratique les plus utilisées, que ce soit pour la sélection en boucle ou encore les jointures vers d'autres tables.
Code :
<?php
$result 
$sql->query_while("SELECT champ1, champ2 FROM ".PREFIX."table WHERE condition ORDER BY champ" $sql->sql_limit(010), __LINE____FILE__);
while(
$row $sql->sql_fetch_assoc($result))
{
    
//Exemple d'utilisation:
    
echo $row['champ1'];
}
$sql->close($result); //On libère la mémoire 
?>

Ce que nous retiendrons :


A partir de cette fonction on peut faire toutes sortes de requêtes. Voici par exemple la requête de sélection de l'index du forum.

Code :
<?php
$result 
$sql->query_while("SELECT c.id AS cid, c.name, c.subname, c.nbr_topic, c.nbr_msg, c.type, c.status, c.secure, t.id AS tid, 
t.idcat, t.title, t.last_timestamp, t.last_user_id, t.last_msg_id, t.nbr_msg AS t_nbr_msg, m.user_id, m.login, v.last_view_id 
$extend_field_s "
FROM "
.PREFIX."forum_cats AS c
LEFT JOIN "
.PREFIX."forum_topics AS t ON t.id = c.last_topic_id
LEFT JOIN "
.PREFIX."forum_view AS v ON v.user_id = '" $userdata['session_user_id'] . "' AND v.idtopic = t.id
LEFT JOIN "
.PREFIX."member AS m ON m.user_id = t.last_user_id
$extend_field "
WHERE c.aprob = 1
ORDER BY c.class ASC"
__LINE____FILE__);
while (
$row $sql->sql_fetch_assoc($result))
{
//Boucle...
}$sql->close($result);
?>


Vous voyez donc que l'utilisation de ces fonctions ne vous limite en rien.

Requêtes d'insertion



Nous allons voir comment insérer des entrées dans la base de données.
Code :
<?php
$sql
->query_inject("INSERT INTO ".PREFIX."table nomchamp1, nomchamp2, ... VALUES ('', '', .....)"__LINE____FILE__); 
?>

Voici ce que nous retiendrons :


Requêtes de modification



Voici comment modifier le contenu d'une table.
Code :
<?php
$sql
->query_inject("UPDATE ".PREFIX."table SET champ1 = '" $valeur_champ1 "', champ2 = '" $valeur_champ2 "' WHERE id = " $id__LINE____FILE__); 
?>


Requêtes de suppression



Pour supprimer des entrées il s'agit encore de la même méthode.
Code :
<?php
$sql
->query_inject("DELETE FROM ".PREFIX."table WHERE id = " $id ""__LINE____FILE__); 
?>


Récapitulatif des requêtes les plus courantes



Voici un bref récapitulatif des méthodes à utiliser pour faire des requêtes dans la base de données. Pour chaque type nous verrons le prototype de la méthode.

Souvenez-vous d'une chose importante: toutes les variables envoyées dans une quelconque requête doivent être sécurisées !
Plus d'informations : partie sécurisation


Fonctions supplémentaires



Nous allons voir ici quelques fonctions supplémentaires permettant d'interagir avec les bases de données.

Dernier id enregistré



Sur mysql cette fonction s'appelle mysql_last_insert_id(). Elle sert à déterminer quel est le dernier id enregistré dans la table. Le champ noté id est celui qui est en auto-incrémentation dans la mesure où la table en est pourvue. Cette fonction n'est pas disponible sur tous les SGBD, c'est pourquoi il va falloir taper une requête supplémentaire au cas où le SGBD ne la gère pas. Voyons un exemple.
Code :
<?php
$last_id 
$sql->sql_insert_id("SELECT MAX(champ) FROM ".PREFIX."table"); 
?>

Ici champ est à remplacer par le nom du champ en auto-incrémentation et table par le nom de votre table.
Sur mysql et les SGBD qui gèrent cette fonction la requête ne sera pas effectuée, mais il est important qu'elle soit correcte.

Nombre de lignes retournées



Ici encore on rencontre le même problème; la fonction mysql_fetch_rows() n'a pas forcément d'équivalent chez les autres SDBD. Pour les mêmes raison que la fonction ci-dessus, la manipulation est légèrement plus compliquée que sous mysql, voici un exemple.
Code :
<?php
$nbr_rows 
$sql->sql_num_rows($ressource_sql"SELECT COUNT(*) FROM ".PREFIX."table WHERE condition"__LINE____FILE__); 
?>

La variable ressource_sql correspond au résultat d'une requête du type query_while.
Dans le cas où cette ressource n'est pas exploitable, on compte manuellement le nombre d'occurrences de façon basique.
Code :
<?php
$nbr_rows 
$sql->sql_num_rows($ressource_sql"SELECT COUNT(*) FROM ".PREFIX."table WHERE condition"__LINE____FILE__)
?>


Gestionnaire de cache



Pour des raisons diverses et multiples il peut être intéressant de mettre en cache des informations. La plus évidente est l'optimisation. En effet il est important de minimiser le nombre de requêtes effectuées dans la base de données, pas tellement pour le temps d'exécution d'une requête (les Systèmes de Gestion de Base de Données sont très rapides), par contre la communication entre le serveur qui gère PHP (Apache en général) et le serveur SQL a un cout en terme de temps. D'autres fois il est impossible de faire une sélection dans la base de données à partir d'une seule requête, là aussi la mise en cache d'informations est très utile.
En quoi consiste la mise en cache ?
Lorsque vous mettez en cache des informations vous créez un fichier qui sera inclu dans votre script lorsque vous désirerez le charger. Ces informations sont présentées sous forme de déclaration de variable (souvent des tableaux) qui contiennent par exemple la configuration de votre module, les catégories de votre forum ou tout un tas d'autres possibilités).

Voyons donc comment utiliser la mise en cache d'informations, sachant que tout est géré par le noyau de PHPBoost.

Indiquer l'utilisation du cache dans la configuration du module



Comme nous l'avons vu dans le chapitre mise en place de la structure du module, il existe un fichier de configuration pour chaque module dans lequel figure notamment une information à propos du cache. Il faudra donc activer le cache dans ce fichier. Pour cela il est nécessaire de l'ouvrir (mon_module/lang/french/config.ini), et mettre si ce n'est pas déjà fait l'index cache à 1 (par défaut il est à 0), de façons à obtenir
Code :
cache=1
.
Vous disposerez dès à présent des fonctionnalités du noyau concernant le gestionnaire de cache pour votre module.

Charger ou régénérer un fichier cache



Le gestionnaire de cache est instancié dans l'objet $cache.
Pour charger un fichier cache il suffit simplement d'utiliser la méthode load_file() qui prend comme argument le nom du fichier à charger. Le code suivant chargera
Code :
<?php
$cache
->load_file('mon_module');
?>


La régénération du cache se passe de la même manière :
Code :
<?php
$cache
->generate_module_file('mon_module');
?>


Mais à partir de quelles données le fichier est-il régénéré ?
En fait c'est vous qui choisissez quelles données vous souhaitez y insérer et comment. Pour cela il va falloir un fichier qui va créer son contenu, ce que nous allons voir dans la partie suivante.


Fichier de génération du cache



Création du fichier



Déjà il faut créer le fichier php qui va vous permettre de régénérer le cache. Il doit se trouver à la racine du dossier de votre module et s'appeler module_cache.php.
Si vous souhaitez utiliser la mise en cache d'informations vous devez créer ce fichier.

Contenu du fichier



Lorsque vous régénérez votre fichier cache, le fichier module_cache.php sera exécuté.
Celui-ci doit contenir la déclaration d'une fonction dont la valeur de retour sera le contenu du fichier php que vous souhaitez mettre en cache.
Cette fonction doit s'appeler generate_module_cache().

Commençons par un exemple de fichier de génération pour comprendre un peu mieux son fonctionnement.