Framework

Environnement base de données

Table des matières

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 :
  • Ici on cherche la valeur du champ champ de la table table.
  • Les constantes __LINE__ et __FILE__ représentent le numéro de la ligne et le nom du fichier qui a appelé la méthode. Cela sert en cas d'erreur pour faciliter le débuggage. Ces constantes sont à rajouter dans toutes une grande majorité des fonctions de l'environnement SQL.
  • Comme on l'a vu la requête est tapée entre guillemets doubles.
  • Le résultat de la requête se trouve directement dans la variable $var. Cette fonction permet de sélectionner un seul champ mais nous allons voir par la suite des fonctions qui permettent de faire tous types de requêtes SQL.


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 :
  • Cette fonction admet un nombre d'arguments variable. Le premier détermine la table dans laquelle la requête va être exécutée. A noter qu'il ne faut pas mettre la constante PREFIX devant, c'est automatiquement fait par la méthode.
  • $var va être un tableau qui contiendra tous les champs listés (arguments 2 à n–4 où n représente le nombre d'arguments).
  • L'argument n-3 représente la condition de sélection.
  • Ici encore on met les constantes __LINE__ et __FILE__.


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 :
  • $result contient le résultat de la requête que nous avons l'habitude de traiter avec mysql_fetch_array(). Ici la fonction dépendant du SGBD elle est incluse dans l'environnement. Ensuite une fois cette méthode appelée l'utilisation est tout à fait habituelle.
  • Ici encore on met les constantes __LINE__ et __FILE__.
  • Cette requête étant assez gourmande en mémoire, il est conseillé de supprimer la variable après utilisation, pour cela on utilise la fonction close de l'environnement.


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 :
  • Pour respecter la norme SQL il est nécessaire de préciser dans un premier temps le nom des champs puis ensuite la valeur qu'on souhaite leur assigner. Pour cela on liste le nom des champs séparé par une virgule puis on met dans VALUES les valeurs correspondantes dans le même ordre.
  • On met encore et toujours les constantes __LINE__ et __FILE__.


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.
  • Requêtes simples: $sql->query(requête, ligne, fichier)
  • Requêtes multiples: $sql->query_array(table, champ1, champ2, ..., champn, condition, ligne, fichier)
  • Requêtes en boucles $sql->query_while(requête, ligne, fichier)
  • Transformation en tableau du résultat d'une requête $sql->sql_fetch_assoc(retour de requête)
  • Libération de la mémoire $sql->close(retour de requête)
  • Insertion, modification et suppression $sql->query_inject()

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.
Cette page a été vue 2187 fois