PHP Interface base de données 01:08:11 Programmation Web 2012-2013
Problème de conception posé Transcription d'un MCD en modèle objet PHP permettant de manipuler la base de données Règles de transcription : Une entité (attributs) devient une classe (attributs) Un enregistrement correspond donc une instance DF / CIF Associations n,m 01:08:11 Programmation Web 2012-2013
MCD modèle objet : Entité <?php class Auteur { private $autid ; private $autnom ; private $autprn ; private $autnaiss ; private $autadr ; private $autcomm ; private $autlogin ; private $autpasswd ; private $autadmin ; private $autmail ; } ?> Auteur AUTID int(11) AUTNOM varchar(50) AUTPRN AUTNAISS AUTADR varchar(255) AUTCOMM AUTLOGIN AUTPASSWD AUTADMIN smallint(6) AUTMAIL varchar(150) 01:08:11 Programmation Web 2012-2013
MCD modèle objet : DF / CIF <?php class Departement { private $depid ; private $depnom ; private $regid ; private $region ; function getRegion() … } class Region { private $regnom ; function getDepartements() … ?> Département DEPID int(11) DEPNOM varchar(50) 1,1 Appartenir 1,n Région REGID int(11) REGNOM varchar(50) 01:08:11 Programmation Web 2012-2013
MCD modèle objet : Association n,m <?php class Camping { private $cmpid ; private $cmpnom ; function getEmplacements() … function getTypePlaces() … } class Emplacements { private $nbPlaces ; private $tplid ; private $camping ; private $typeplace ; function getCamping() … function getTypePlace() … ... Camping CMPID int(11) CMPNOM varchar(50) 1,n Emplacements nbPlaces 0,n TypePlace TPLID int(11) TPLNOM varchar(50) 01:08:11 Programmation Web 2012-2013
MCD modèle objet : Association n,m ... class TypePlace { private $tplid ; private $tplnom ; function getCampings() … function getEmplacements() … } ?> Camping CMPID int(11) CMPNOM varchar(50) 1,n Emplacements nbPlaces 0,n TypePlace TPLID int(11) TPLNOM varchar(50) 01:08:11 Programmation Web 2012-2013
Problème de conception posé <?php class Auteur { private $autid ; private $autnom ; private $autprn ; private $autnaiss ; private $autadr ; private $autcomm ; private $autlogin ; private $autpasswd ; private $autadmin ; private $autmail ; public function __construct(...) … public function lecture($id) public function ecriture() } ?> Table Auteur AUTID int(11) AUTNOM varchar(50) AUTPRN AUTNAISS AUTADR varchar(255) AUTCOMM AUTLOGIN AUTPASSWD AUTADMIN smallint(6) AUTMAIL varchar(150) 01:08:11 Programmation Web 2012-2013
Problème de conception posé <?php class Personne { private $persid ; private $grpnum ; private $persnom ; private $persprnm ; private $persad ; private $perscp ; private $persville ; private $perstel ; private $persmail ; private $persetat ; public function __construct(...) … public function lecture($id) public function ecriture() } ?> Table Personne PERSID int(11) GRPNUM PERSNOM varchar(50) PERSPRNM PERSAD varchar(100) PERSCP varchar(5) PERSVILLE PERSTEL varchar(10) PERSMAIL PERSETAT varchar(20) 01:08:11 Programmation Web 2012-2013
Approche proposée Créer un modèle des objets "ligne BD" Doivent pouvoir gérer un enregistrement : les valeurs et leurs étiquettes gestion des entrées / sorties avec la BD : lecture / insertion / mise à jour accès aux valeurs de façon sure modification des valeurs de façon sure affichage production de formulaire d'insertion / modification chargement à partir de données issues d'un formulaire / de la lecture de la base de données 01:08:11 Programmation Web 2012-2013
Conception du modèle Classe ? Classe abstraite ? Interface ? attributs méthodes concrètes pas de méthodes "obligatoires" Classe abstraite ? méthodes abstraites "obligatoires" Interface ? méthodes "obligatoires" 01:08:11 Programmation Web 2012-2013
Gestion des attributs (1) Solution classique : ajout de données membres dans la classe concernée impossibilité d'écrire des méthodes génériques à un niveau supérieur de la hiérarchie gestion des étiquettes associées aux valeurs ? Approche proposée : tableau associatif des valeurs d’une ligne d’une table confinement, itération, accès facilité possibilité d'écrire des méthodes génériques tableau associatif des étiquettes associées aux valeurs méthode d'initialisation du tableau des valeurs 01:08:11 Programmation Web 2012-2013
Conception du modèle Classe ? Classe abstraite ? Interface ? attributs méthodes concrètes pas de méthodes "obligatoires" Classe abstraite ? méthodes abstraites "obligatoires" Interface ? méthodes "obligatoires" 01:08:11 Programmation Web 2012-2013
Initialisation de l'objet Approche proposée Constitution d'une classe générique : tableau associatif des valeurs Clés = noms des champs de la table Valeurs = valeurs d'une ligne de la table Auteur class Auteur extends Enregistrement Enregistrement __construct() initAttributs() Enregistrement __construct() initAttributs() $valeurs clé valeur $valeurs clé valeur 'AUTID' null 'AUTNOM' $valeurs clé valeur 'AUTID' 1234 'AUTNOM' "Zola" $valeurs clé valeur Initialisation de l'objet Lecture dans la BD Création de l'objet 01:08:11 Programmation Web 2012-2013
Gestion des attributs (2) class Enregistrement { // Attributs de l'enregistrement protected $valeurs = array() ; /* Initialisation des noms des champs qui sont les clés du tableau $valeurs */ protected function initAttributs( $_cles /* Tableau des clés */) { $this->valeurs = array() ; foreach (array_keys($_cles) as $cle) $this->valeurs[$cle] = null ; } 01:08:11 Programmation Web 2012-2013
Accès aux attributs Solutions possibles : Accès R/W par $aut->valeurs['AUTID'] Accès R par $aut->donne('AUTID') Accès W par $aut->affecte('AUTID', 12) Accès R/W par $aut->AUTID Confinement Itération possible Accès sûr ? Accès simple ? Auteur Enregistrement __construct() initAttributs() $valeurs 'AUTID' 1234 'AUTNOM' "Zola" $valeurs doit être public ! Syntaxe assez lourde Surcharge de __get() et __set() 01:08:11 Programmation Web 2012-2013
Gestion des attributs (3) /* Surcharge de __get pour donner accès aux valeurs sous la forme $e->un_champs */ public function __get( $_cle /** Nom du champs */) { if (array_key_exists($_cle, $this->valeurs)) return $this->valeurs[$_cle] ; throw new Exception( "Champs '$_cle' inconnu dans '" .get_class($this)."'") ; } 01:08:11 Programmation Web 2012-2013
Gestion des attributs (4) /* Surcharge de __set pour donner accès aux valeurs sous la forme $e->un_champs=val */ public function __set( $_cle /** Nom du champs */, $_val /** Nouvelle valeur */) { if (array_key_exists($_cle, $this->valeurs)) return $this->valeurs[$_cle] = $_val ; throw new Exception( "Champs '$_cle' inconnu dans '" .get_class($this)."'") ; } 01:08:11 Programmation Web 2012-2013
Gestion des étiquettes Valeurs : Tableau associatif au niveau de la classe mère Accès simple à l'aide de __get et __set Traitements au niveau de la classe mère Méthode d'initialisation initAttributs($_cles) Étiquettes : Tableau associatif Propriété de la classe mère ? Communes à toutes les entités d'une classe dérivée Attribut statique de la classe dérivée Méthode abstraite etiquettes() (classe mère) Utilisable pour l'initialisation des attributs 01:08:11 Programmation Web 2012-2013
Définition des méthodes (1) Chargement de données : à partir de données issues d'un formulaire (tableau) à partir de la lecture de la base de données (tableau) possible si les clés de ces tableaux sont identiques à celles du tableau des valeurs démarche : pour chaque clé du tableau des valeurs, si cette dernière est présente dans le tableau des données fournies alors affecter la valeur fournie implémentation possible dans la classe mère 01:08:11 Programmation Web 2012-2013
Définition des méthodes (2) Lecture BD nécessite : de connaître la table de connaître la clé primaire de transférer les données lues dans les valeurs Écriture BD nécessite : de savoir si l'on doit insérer ou mettre à jour la table lecture préalable de disposer des valeurs 01:08:11 Programmation Web 2012-2013
Définition des méthodes (3) Connaître la table : Donnée des classes dérivées A la charge des classes dérivées Obligation d'implémentation méthode abstraite table() de la classe mère Connaître la clé primaire : Obligation d'implémentation méthode abstraite cle_pri() de la classe mère 01:08:11 Programmation Web 2012-2013
Bilan (partiel) des méthodes Auteur Enregistrement table()"Auteur" cle_pri()"AUTID" etiquettes()… __construct() initAttributs() lecture() ecriture() Enregistrement table() cle_pri() etiquettes() __construct() initAttributs() lecture() ecriture() class Auteur extends Enregistrement $valeurs clé valeur $valeurs 'AUTID' 1234 'AUTNOM' "Zola" 01:08:11 Programmation Web 2012-2013
Définition des méthodes (4) Lecture : table / clé primaire connues SELECT * FROM table WHERE clé_pri=id Chargement Écriture : Si id existe dans la base mise à jour SELECT COUNT(*) FROM table WHERE clé_pri=id == 1 UPDATE table WHERE clé_pri=id Sinon insertion SELECT COUNT(*) FROM table WHERE clé_pri=id == 0 INSERT INTO table 01:08:11 Programmation Web 2012-2013
Définition des méthodes (5) Affichage : Peut être fait de façon générique grâce au parcours des attributs et étiquettes Serait plus judicieux d'être spécialisé par les classes dérivées Production de formulaire : Éléments de formulaire et non formulaire complet 01:08:11 Programmation Web 2012-2013
Bilan (1) abstract class Enregistrement { protected $valeurs = array() ; abstract public function __construct($_id=null) ; protected function initAttributs($_cles) { … } abstract protected function table() ; abstract protected function cle_pri() ; abstract public function etiquettes() ; public function etiquette($_cle) { … } public function lecture($_id) { … } public function ecriture() { … } public function chargement($_donnees) { … } public function affichage() { … } public function formulaire() { … } 01:08:11 Programmation Web 2012-2013
Bilan (2) public function __get($_cle) { … } public function __set($_cle, $_val) { … } public function __isset($_cle) { … } public function __unset($_cle) { … } } // Fin class Enregistrement class Etendue extends Enregistrement { const table = "la_table" ; const cle_pri = "LA_CLE_PRI" ; static private $labels = array('XXXXX' => 'Etiquette X', ...) ; public function __construct($_id=null) { $this->initAttributs(self::$labels) ; if (isset($_id)) $this->lecture($_id) ; } 01:08:11 Programmation Web 2012-2013
Bilan (3) protected function table() { return self::table ; } protected function cle_pri() { return self::cle_pri ; protected function etiquettes() { return self::$labels ; public function affichage() { // ... public function formulaire() { // ... } // Fin class Etendue 01:08:11 Programmation Web 2012-2013
Implémentations plus élaborées Requête d'information Liste des champs Nature des champs Type de clé 01:08:11 Programmation Web 2012-2013