2. L'accès aux données

Les accès natifs

La communication entre un client, l'application, et le SGBD, le serveur, s'établit en utilisant les protocoles réseau classiques :

    • l'application communique avec le logiciel client du SGBD, pour lui demander d'exécuter une requête ;
    • le logiciel client SGBD établit une connexion avec le serveur, en envoyant une requête qui va contenir l'adresse IP de ce dernier, et le port TCP utilisé par le SGBD pour « écouter » le réseau (par exemple, pour MYSQL, le port TCP « standard » est le 3306, pour SYBASE ASE sous Windows ou Linux, c'est le port 5000). La requête contient également l'adresse IP du poste client, et le port TCP auquel il faudra retourner les résultats (le port TCP est choisi aléatoirement par le système) ;
    • le serveur reçoit la requête, l'oriente vers l'application SGBD, grâce au port TCP indiqué dans la requête ;
    • le SGBD traite la requête, puis renvoie le résultat de son exécution au client, grâce à l'adresse IP et au port TCP fourni ;
    • le poste client reçoit la requête, la transmet au client SGBD ;
    • le client SGBD fournit à l'application les résultats de la requête.

Les échanges avec le SGBD ne sont pas normalisés : chaque éditeur a mis en place ses propres stratégies pour établir le dialogue, formater les données... C'est pourquoi nous sommes obligés d'installer, sur chaque poste client, le logiciel qui permettra d'établir la communication avec le SGBD.

L'approche Objet dans les SGBD

Lorsque les mécanismes Objet ont été décrits, et notamment avec l'avènement de UML, certains chercheurs ont essayé d'abord de créer des bases de données objet, dont le résultat a été très mitigé : les bases de données manipulant des objets sont assez rares, tout simplement parce que le langage SQL, s'il n'est pas parfait, présente l'avantage d'être simple, efficace, et universel. Aujourd'hui, les mécanismes objets ne sont implémentés que pour des usages bien spécifiques. Certains auteurs considèrent que les annuaires à la norme LDAP peuvent être assimilés à des bases de données Objet. On retrouve également ce mécanisme implémenté dans des bases de données SQL classiques : ORACLE, par exemple, a introduit un objet appelé « cartouche spatial », qui permet de manipuler les informations utilisées dans les systèmes d'informations géographiques. POSTGRESQL dispose, lui aussi, de son objet géographique, implémenté dans l'extension POSTGIS.

Le langage SQL, dans sa version 3 (SQL-3 ou SQL-99) a intégré quelques mécanismes issus de la recherche sur les objets, comme l'héritage, qui se retrouve aujourd'hui dans le SGBD POSTGRESQL.

L'héritage

POSTGRESQL implémente un concept intéressant, l'héritage de tables. Par exemple, une table Personne pourra être héritée dans une table Beneficiaire, cette dernière étant liée aux dossiers d'aide ou aux RIB utilisés pour le paiement. Ces deux tables, Personne et Beneficiaire, pourront être manipulées de façon très simple avec les extensions SQL de la norme SQL:1999.

Toutefois, la norme SQL:1999 n'a quasiment jamais été implémentée. Concevoir des bases de données selon ce système revient donc à travailler exclusivement avec la base de données POSTGRESQL : ce n'est pas forcément une mauvaise solution, mais il faut que les avantages apportés par le choix de ce gestionnaire de bases de données soient déterminants. Ce SGBD est souvent choisi d'ailleurs en raison de la disponibilité de son objet géographique, dont nous parlerons au paragraphe suivant.

Quant à l'héritage, ce mécanisme peut être contourné en travaillant avec des tables liées. Pour reprendre nos deux tables Personne et Beneficiaire, il suffit que Beneficiaire dispose de la même clé que Personne et qu'une jointure soit réalisée entre les deux tables pour arriver quasiment au même mécanisme.

L'objet géographique

La seconde approche a été mise en œuvre principalement pour gérer le stockage des informations géographiques. Pour stocker un polygone ou un point, il faut indiquer des coordonnées, des cheminements (le contour du polygone...), et il faut disposer également de fonctions pour les manipuler. ORACLE et POSTGRESQL, avec son extension POSTGIS, ont intégré depuis quelques années un objet géographique, qui permet de manipuler une information en une seule opération, ce qui simplifie grandement les opérations dans les systèmes d'informations géographiques.

Accéder à la base de données en développement Objet

Les concepts de base

Ne pas confondre le modèle relationnel et l'application Objet !

Les modèles objet, et notamment le diagramme de classes, ressemblent fortement à un modèle relationnel (modèle conceptuel des données Merise, par exemple). La tendance est forte de dessiner un diagramme de classes, qui sera utilisé tel quel pour générer la base de données et, par extension, manipuler les données.

Cette approche présente un inconvénient majeur : elle ne tient pas compte de la nature intrinsèque des SGBD.

Les SGBD sont conçus pour répondre à une requête. Cette requête est émise dans un langage, le SQL, et le SGBD peut renvoyer des informations (une collection) et un code d'erreur. Le contenu de la requête n'influe en rien sur la manière dont les communications s'établissent entre l'application et le SGBD.

D'une manière générale, pour exécuter une requête SQL, c'est le fonctionnement suivant qui est le plus fréquemment mis en œuvre :

Dans cet exemple, le navigateur (l'utilisateur) demande l'ouverture d'un module (une page PHP). Ce dernier va demander à la classe d'accès à la base de données (AccesBDD) d'exécuter une requête SQL. C'est la classe AccesBDD qui va implémenter les commandes spécifiques du SGBD, et non le module directement.

Ce schéma est valable quelle que soit la requête, qu'elle soit de sélection, de modification ou de suppression... La méthode Execute va retourner une collection dans le cas d'une commande de sélection, ou simplement un code de retour en cas d'exécution d'une commande de mise à jour.

Il s'agit, ici, d'un exemple très simple : si ce schéma était conservé en l'état, il faudrait coder toutes les requêtes SQL dans tous les modules, ce qui irait à l'encontre du but recherché, à savoir un codage unique dans l'application.

Il existe plusieurs bibliothèques en PHP qui permettent d'accéder au données en intercalant une couche d'abstraction. Celle-ci va prendre en charge les différentes commandes utilisées pour se connecter et exécuter les requêtes, et permettre au développeur de s'affranchir du type de SGBD utilisé.

Plusieurs grandes bibliothèques sont disponibles en PHP actuellement : celle implémentée dans Zend Framework (classes Zend_db et connexes), qui s'appuie sur PDO (Php Data Objects, une couche d'accès intégrée dans PHP depuis PHP5), celle présente dans PEAR, ou ADODB.

L'utilisation d'une couche d'abstraction ne doit pas faire oublier que seules les requêtes standard seront prises en charge quel que soit le SGBD : il ne faut pas oublier que chaque éditeur a rajouté ses propres extensions. Néanmoins, il est très souvent possible de les masquer en les intégrant dans des vues, codées directement dans la base de données.

Concevoir les objets de traitement

Nous l'avons vu, l'application d'un modèle relationnel n'a pas vraiment de sens en programmation objet. Néanmoins, un de ses objectifs est de ne coder qu'une seule fois, et de pouvoir réutiliser le code à d'autres endroits : des modules seront développés pour pouvoir retrouver une classe d'informations rapidement, quel que soit leur moment d'utilisation.

La conception de l'application va passer par les phases suivantes :

    • description des objets de traitement nécessaires au sein de l'application ;
    • déduction d'un schéma relationnel ;
    • création de la base de données dans le SGBD choisi ;
    • codage des objets de traitement.

Pour comprendre le mécanisme, nous allons prendre comme exemple la gestion d'un dossier de subvention. L'application doit permettre de stocker les informations concernant un dossier de subvention. La subvention concerne un bénéficiaire, qui peut disposer de plusieurs adresses (postales, siège social, atelier...), de plusieurs comptes bancaires représentés par des relevés d'identité bancaires (RIB) (…)

De cet exemple, nous pouvons en déduire le diagramme de classe suivant :

Ce schéma permet de préciser :

    • qu'un dossier comporte au moins un bénéficiaire ;
    • qu'un bénéficiaire peut avoir plusieurs adresses (adresse postale, adresse de résidence et, pour une société, siège social, atelier...) ;
    • qu'un bénéficiaire peut disposer de plusieurs RIB (relevés d'identité bancaire), dont un seul sera utilisé dans le dossier.

En ce qui concerne la création des objets, si l'adresse avait été unique, nous n'aurions pas eu besoin de créer une classe spécifique : elle aurait fait partie des attributs de la classe Beneficiaire.

Il en est de même pour le RIB, qui pourrait être considéré comme un attribut de la classe Dossier. Mais si nous voulons rajouter un programme de vérification de la clé, afin de s'assurer que le RIB saisi soit bien correct, il vaut mieux créer alors une classe RIB qui contiendra alors la fonction permettant de vérifier sa validité.

A partir de ce diagramme, nous pouvons en déduire le schéma de la base de données :

Cette représentation permet de visualiser la table DossierBeneficiaire, qui est porteuse de la relation n-n entre les tables Dossier et Beneficiaire (cette relation particulière sera détaillée ultérieurement). Le RIB est stocké dans une table à part, pour pouvoir représenter les différents RIB possédés par un bénéficiaire. Il en est de même pour les adresses, qui sont typées (adresse postale, de résidence...).

Quelques règles d'écriture de la base de données

Il n'existe pas de norme particulière, qui va « dire » comment doit être construite une base de données. Au moment de la conception des tables, quelques concepts doivent être conservés à l'esprit :

    • il faut faire simple : plus la base de données sera simple, plus elle sera facile à manipuler ;
    • il faut rester dans le modèle relationnel : l'information est stockée une et une seule fois ;
    • on n'introduit pas de « règles métier » (par exemple, le montant de la subvention ne doit pas dépasser 50 % du devis accepté) dans la base de données : c'est dans l'application qu'elles seront codées1. Elles peuvent évoluer au cours du temps, et il est beaucoup plus complexe de modifier une base de données qu'une application.

Les SGBD sont souvent sensibles à la casse (les minuscules et les majuscules sont reconnues comme des caractères différents). Cette caractéristique va pouvoir être utilisée pour rendre notre base de données lisible.

Voici un libellé de colonne, volontairement long, écrit dans trois styles différents :

releveidentitebancairedossierdepret

RELEVEIDENTITEBANCAIREDOSSIERDEPRET

ReleveIdentiteBancaireDossierDePret

Le moins lisible est celui écrit en majuscule ; c'est, hélas, une habitude fréquente d'écrire les tables et les colonnes dans cette casse, en partie d'ailleurs à cause des outils de dessin des bases de données, qui proposent fréquemment par défaut la génération des tables dans ce mode. Le troisième est le plus lisible, simplement parce que chaque mot est isolé des autres en le commençant par une majuscule. C'est une notation appelée parfois « à l'allemande », qu'il est conseillé de privilégier.

Il faut faire également attention à ne pas utiliser d'accents ou de caractères spéciaux : selon le jeu de codage des caractères utilisé, le résultat peut être parfois désastreux.

Attention toutefois si vous travaillez avec PostgreSQL : si vous employez des majuscules dans les noms des colonnes, vous devrez entourer les colonnes du caractère "double-quotes" (normalisation SQL). Cela peut être parfois un peu compliqué...

Utiliser les schémas

La plupart des SGBD gèrent la notion de schéma. Par défaut, les tables sont écrites dans le schéma « public », mais vous pouvez créer d'autres schémas.

Quelques conseils :

- stockez les données « métiers » dans le schéma public ;

- créez des schémas pour gérer des aspects particuliers de l'application. Par exemple, si vous avez besoin de réaliser des imports, les tables permettant de décrire ces imports pourront être utilement stockées dans un schéma dédié à cet usage, par exemple « import ». De même, si la gestion des droits nécessite des tables particulières, stockez les dans un schéma adéquat ;

- créez également des schémas pour des usages spécifiques, par exemple pour isoler un sous-ensemble de la base de données destiné à être exporté. Dans ce schéma, vous pourrez ne créer que des vues (avec critères de sélection spécifiques), qui permettront d'obtenir un sous-ensemble de vos données en fonction de critères déterminés à l'avance.

En résumé...

Au moment de créer une base de données, il vaut mieux :

    • préférer une notation « à l'allemande », en faisant commencer chaque partie du nom du champ d'une majuscule. Si vous travaillez avec PostgreSQL, n'utilisez que des minuscules, et séparez les mots par le caractère _ ;
    • nommez les clés étrangères avec le même nom que les clés primaires auxquelles elles sont liées : cela facilitera la création des jointures ;
    • si vous avez des noms de colonnes qui risquent de se retrouver dans plusieurs tables, préfixez-les du nom de la table (personne_id, personne_nom...) ;
    • utiliser systématiquement des clés non significatives, numériques, auto-incrémentées ;
    • pour les tables de type N-N, les nommer en concaténant le nom des tables liées, en commençant par la table principale de la relation ;
    • gérer les différentes versions, pour s'assurer que le code de l'application sera compatible avec les dessins des tables ;

et, bien sûr, respecter les règles qui auront été fixées...

La couche d'abstraction

Chaque SGBD disposant de son propre jeu d'instructions, les programmeurs ont depuis longtemps cherché à s'affranchir le plus possible de la base de données pour réaliser un code portable : l'application peut être développée en s'appuyant sur une base de données PostGreSQL, puis porter l'application sous Oracle ou Sybase, par exemple.

En PHP, les initiatives pour s'abstraire du type de la base de données sont nombreuses. Dans la pratique, elles présentent toutes à peu près le même fonctionnement :

    • un objet est créé, qui va gérer la connexion à la base de données ;
    • les requêtes sont plus ou moins préparées automatiquement avant l'exécution.

Les bibliothèques d'abstraction les plus connues, aujourd'hui, sont les suivantes :

    • ADODB : cette bibliothèque est une des plus anciennes. Elle a été créée en 2000, et est mature. Elle est très couramment utilisée, et fonctionne tant en PHP 4 qu'en PHP 5. On la retrouve intégrée dans la plupart des projets développés ces dernières années ;
    • PEAR::MDB2 : c'est le composant d'accès aux données de PEAR (PHP Extension and Application Repository, ensemble de classes destinées à faciliter la vie du programmeur). Il couvre les bases de données les plus courantes ;
    • PDO : (PHP Data Objects) : c'est une bibliothèque qui a été intégrée dans le moteur de PHP, et qui couvre la plupart des bases de données. Les requêtes sont en général exécutées ainsi :
$stmt=$bdd->prepare("INSERT INTO Beneficiaire (nom,prenom) VALUES (?, ?)");
$stmt->bindParam(1, $nom);
$stmt->bindParam(2,$prenom);
//insertion d'une ligne
$nom='Dupont'';
$prenom='Jean';
$stmt->execute();
    • Zend_Db_Adapter : c'est un composant du framework Zend. Il s'appuie sur PDO pour les accès aux bases de données, mais en améliore l'approche objet. Il se distingue des autres classes par deux caractéristiques : d'une part, les requêtes SQL peuvent être montées « par morceau », en déclarant à part les clauses WHERE, ORDER..., et d'autre part, il est possible de décrire complètement la structure relationnelle de la base de données, et de lui demander de gérer les contraintes d'intégrité, tant pour les opérations d'écriture que de suppression.

la bibliothèque ADODB

ADODB (http://adodb.sourceforge.net/) est une bibliothèque d'abstraction d'accès aux bases de données, disponible sous PHP et PYTHON. Elle encapsule les accès aux différentes bases de données, sans que le développeur ait besoin de connaître les différentes commandes spécifiques à chacune.

Elle permet d'accéder à quasiment toutes les bases de données disponibles : MySQL, PostgreSQL, Interbase, Firebird, Informix, Oracle, MS SQL, Foxpro, Access, ADO, Sybase, FrontBase, DB2, SAP DB, SQLite, Netezza, LDAP, ODBC, ODBTP. Il est également possible de rajouter ses propres connecteurs, si c'est nécessaire. C'est, à ce jour, très certainement la bibliothèque la plus riche disponible en PHP.

La gestion des exceptions est également disponible sous PHP5. Une version compilée, en langage C, peut également être installée sur le serveur web, ce qui permet d'accélérer nettement son exécution : la bibliothèque reconnaît automatiquement la présence du programme compilé et lui transmet l'exécution des instructions.

De façon simple, pour utiliser ADODB, nous avons besoin de quelques lignes de code.

Pour commencer, les informations concernant la base de données sont stockées dans des variables :

$BDD_type = "mysql"; // Base de données de type MYSQL
$BDD_server = "localhost"; // Adresse du serveur de base de données
$BDD_login = "proto"; // Login de connexion à la base de données
$BDD_passwd = "proto"; // Mot de passe associé au login
$BDD_database = "proto"; // Nom de la base de données

Puis les bibliothèques ADODB sont chargées, ici depuis le dossier plugins/adodb :

include_once('plugins/adodb/adodb.inc.php');

et la connexion à la base de données est établie :

if (!isset($bdd)) {
// La connexion n'existe pas
$bdd = ADONewConnection($BDD_type);
$etatconn=$bdd->Connect($BDD_server, $BDD_login, $BDD_passwd, $BDD_database);
if ($etatconn == FALSE) {
echo( "La connexion a la base de donnees a echoue" );
die ();
}
}

L'application est maintenant connectée à notre base de données.

Nous allons exécuter maintenant une requête de sélection. Tout d'abord, la requête SQL est préparée :

$sql = "select * from Dossier";

Nous indiquons à notre objet ADOConnexion de travailler dans un mode particulier : chaque colonne sera identifiée par son nom (et non par le numéro de champ)

$bdd->SetFetchMode(ADODB_FETCH_ASSOC);

La requête SQL est exécutée. Une instance de l'objet ADORecordSet, contenant le résultat de cette requête va être créé, $rs :

$rs = $bdd->execute($sql);
if(!$rs)
{
$collection=false;
print $bdd->ErrorMsg();
} else {
$collection = array();
$collection = $rs->GetRows($rs->RecordCount());
}

$collection est un tableau indexé à deux dimensions. La première dimension correspond aux lignes retournées (numérotées de 0 à n), la seconde aux champs de chaque ligne.

Le couplage relationnel-Objet

Objectifs

Nous l'avons vu, la gestion de l'ensemble des opérations concernant une table, à savoir la lecture ou l'écriture des informations nécessite l'écriture d'un code particulièrement important, et qui est particulièrement fastidieux à rédiger.

Ainsi, pour une requête d'écriture, il faut :

    • vérifier les données à intégrer dans la base de données, par exemple, s'assurer que les champs numériques ne contiennent pas des caractères ;
    • transformer les dates issues du navigateur dans le format attendu par la base de données ;
    • le cas échéant, s'assurer que les données ne présentent pas de risque de sécurité ;
    • vérifier si c'est une requête d'insertion (INSERT) ou de modification (UPDATE) qu'il faut exécuter ;
    • pour chaque champ à mettre à jour, vérifier s'il est du type numérique ou texte et, le cas échéant, l'entourer de guillemets ;
    • exécuter la requête ;
    • vérifier si celle-ci s'est bien exécutée ;
    • et enfin, s'il s'agit d'une requête d'insertion, et que les enregistrements sont identifiés avec une clé automatique (clé auto-incrémentée), récupérer l'identifiant de l'enregistrement inséré.

La tentation est grande de vouloir encapsuler ces opérations dans une classe générique, qui réalisera toutes ces opérations à notre place.

Dans le cadre de la programmation objet, ce mécanisme est parfois appelé couplage relationnel-objet (ou ORM en anglais, Object Relational Mapping).

2.quelques bibliothèques connues

DOCTRINE : s'appuyant sur PDO pour les accès aux bases de données, cette bibliothèque gère les relations entre les tables et crée automatiquement les jointures, en les déduisant d'un schéma défini à partir des classes d'accès. Il faut décrire la structure et les relations dans les classes dérivées (par exemple, Beneficiaire).

EzComponents : il s'agit d'un ensemble de bibliothèques PHP, qui dispose d'un module d'accès aux données.

EZPDO : cette bibliothèque est basée elle aussi sur PDO. La structure de la base de données doit être décrite dans des zones de commentaires (balise @ORM), selon la norme de documentation PhpDocumentor (cf. chapitre 6, la structuration de l'application).

JDAO : intégré à Jelix, un atelier d'application 100 % objet. JDAO est basé sur une description de la base de données dans un fichier XML.

METASTORAGE : c'est une application qui va générer automatiquement les classes d'accès aux données, à partir d'un schéma XML.

PHPMYOBJECT : il fonctionne en natif avec les bases de données MySQL ou PostgreSQL, et peut s'appuyer sur les pilotes PDO. Il déduit intégralement la structure des tables en interrogeant la base de données (si la structure ne peut être déduite, elle peut être décrite dans une classe).

PROPEL : intégrée à Symphony un framework (squelette d'application - cf. chapitre 8, La conception selon le modèle MVC – les frameworks), elle s'appuie sur un fichier XML pour décrire la base de données, qui peut être généré automatiquement.

ZENDdbTable : ce composant est intégré à Zend Framework, s'appuie sur PDO pour les accès aux données, et dispose de fonctions avancées pour gérer les contraintes au sein de la base de données.

la classe OBJETBDD

La classe OBJETBDD (http://objetbdd.sourceforge.net), étudiée ici, présente l'avantage de s'appuyer sur ADODB pour gérer les accès à la base de données ; elle peut donc, en théorie, être utilisée quel que soit le moteur de base de données utilisé.

De plus, la plupart des classes ORM s'appuient sur des mécanismes qui récupèrent automatiquement le type des colonnes. Malheureusement, cela ne fonctionne pas avec toutes les bases de données ; ObjetBDD permet de contourner ce problème, mais impose en contrepartie une déclaration manuelle des colonnes qui ne sont pas de type texte pour fonctionner correctement.

Une autre différence tient au mode d'insertion des données. La plupart des ORM utilisent une assignation de variable directe (par exemple, $maclasse->nom = 'Dupont'), ObjetBDD travaille avec des tableaux ($donnees = array('nom'=>'Dupont').

Enfin ObjetBDD réalise un certain nombre de contrôles avant l'insertion en base de données, gère automatiquement la transformation des dates depuis le format de la base de données vers l'affichage de l'utilisateur, et encode les caractères spéciaux HTML pour limiter les risques d'attaque par « cross site scripting ».

OBJETBDD est une classe non instanciable, qui doit donc par conséquent être héritée. Elle s'insère ainsi au sein de nos objets :

ObjetBDD utilise une instance ADOConnection pour réaliser les opérations sur la base de données.

L'ensemble des objets qui vont être utilisés pour manipuler les informations dans la base de données vont hériter de ObjetBDD.

exemple de création de la classe Beneficiaire :

Pour utiliser cette classe :

include_once('objetBDD/ObjetBDD.php');
class Beneficiaire extends ObjetBDD {
function __construct($bdd, $param=NULL){
$this->table="Beneficiaire";
$this->colonnes = array(
"IdBeneficiaire"=>array("type"=>1,"requis"=>1),
"DateNaissanceBeneficiaire"=>array("types"=>2),
"NomBeneficiaire"=>array("longueur"=>30,"pattern"=>"#^[a-zA-Z]+$#","requis"=>1),
"PrenomBeneficiaire"=>array("longueur"=>20),
"MelBeneficiaire"=>array("pattern"=>"#^.+@.+\.[a-zA-Z]{2,6}$#")
);
parent::__construct($link, $param);

Les différents types d'informations qui peuvent être déclarés pour chaque colonne sont les suivants :

Par défaut, OBJETBDD adopte le comportement suivant :

    • les identifiants des tables sont considérés comme des clés automatiques, auto-incrémentées ;
    • les dates sont transformées sous la forme jj/mm/aaaa en lecture, et retraduites dans l'autre sens pour l'écriture ;
    • les données sont systématiquement vérifiées avant d'être écrites ;
    • les messages d'exécution SQL ne sont affichés qu'en cas d'erreur ;
    • les caractères particuliers HTML ( les signes <, >, &, guillemets doubles) sont transformés en leur équivalent HTML (&lt;, $gt;, &amp;, &quot; respectivement) lors de la lecture, et inversement lors des opérations d'écriture.

Les principales méthodes disponibles :

Exemple d'utilisation :

include_once('adodb.inc.php');
$bdd = ADONewConnection($BDD_type);
$bdd->Connect($BDD_server, $BDD_login, $BDD_passwd, $BDD_database);
include_once('ObjetBDD.php');
include('beneficiaire.class.php');
$beneficiaire = new Beneficiaire($bdd);
$id = 5;
$data = $beneficiaire->lire($id);
print_r($data);

Comment intégrer la classe dans l'application ? En principe, la modification d'une information passe par trois phases :

    • d'abord, la liste des enregistrements disponibles est affichée ;
    • puis c'est au tour du détail de l'enregistrement qui nous intéresse, qui sera modifié dans un formulaire ;
    • et enfin, les modifications sont écrites en base de données.

L'affichage de la liste des enregistrements va impliquer les opérations suivantes :

    • le navigateur appelle le module PHP à exécuter (la page PHP) ;
    • le module crée une instance de notre classe Beneficiaire, et lui demande d'exécuter la fonction getListe() ou getListeParam($sql) ;
    • la classe Beneficiaire demande à l'instance de classe ADODB d'exécuter la requête, puis retourne le tableau contenant le résultat de la sélection au module PHP ;
    • le module PHP prépare l'affichage ;
    • et enfin, il envoie la page au navigateur, pour que l'utilisateur puisse visualiser le résultat.

Voici d'abord l'affichage de la liste :

Puis la lecture d'un enregistrement :

Et enfin, la mise en fichier, et le réaffichage de l'information écrite :

1En fait, il est possible de stocker ce type d'informations dans la base de données, mais en utilisant des procédures stockées ou des triggers qui pourront être modifiés sans toucher à la structure des données. C'est un choix d'architecture qui est plus fréquent dans les grands systèmes.