PhpMyObject manuel

Date de publication : 29/07/2007 , Date de mise à jour : 29/12/2007

Par Nicolas BOITEUX

PMO est une API d騅elopp馥 en PHP. Un Object relational Mapping (ORM) qui transforme les r駸ultats de requ黎es SQL en objets. PMO est bas? en parti sur le motif de conception Active record. PMO g鑽e les relations 1:1, 1:n, n:m.

???????????? ? Version PDF (Miroir) ? Version hors-ligne (Miroir)

I. Introduction
II. Pourquoi utiliser PMO ?
III. Fonctionnement global
IV. Le controlleur PMO_MyController
V. Les objets PMO_MyObject
VI. Les objets PMO_MyTable
VI. Les maps PMO_MyMap
VIII. Le class loader
IX. Les Exceptions
X. Exemples
XI. Exemple de controleurs
XII. Remerciements


I. Introduction

Source wikipedia: "En g駭ie logiciel, le patron de conception (design pattern) active record est une approche pour lire les donn馥s d'une base de donn馥s. Les attributs d'une table ou d'une vue sont encapsul駸 dans une classe. Ainsi l'objet, instance de la classe, est li? ? un tuple de la base. Apr鑚 l'instanciation d'un objet, un nouveau tuple est ajout? ? la base au moment de l'enregistrement. Chaque objet r馗up鑽e ses donn馥s depuis la base; quand un objet est mis ? jour, le tuple auquel il est li? l'est aussi. La classe impl駑ente des accesseurs pour chaque attribut."

Ce manuel d馗rit la version 0.12. Il va vous apprendre ? utiliser PMO et ? d騅elopper plus simplement et plus rapidement vos applications PHP.


II. Pourquoi utiliser PMO ?

Voici les raisons pour lesquelles PMO est succeptible de vous int駻resser:

  • pour faire de l'orient? objet
  • pour ne pas recoder 50 fois les m麥es classes
  • pour manipuler votre base de donn馥 en 3 lignes
  • pour rendre r騏tilisable ces classes
  • pour encapsuler la gestion des donn馥s dans des classes d馘i馥s ? cela
Voici les raisons pour lesquelles PMO est succeptible de vous int駻resser par rapport aux autres ORM PHP:

  • il est simple
  • il ne remplace pas SQL
  • il d馗ouvre automatiquement les sch駑as de la base (pas de fichiers XML ? manipuler)
  • il utilise des interfaces,
  • il est con輹 ? partir d'une architecture logiciel (UML)
  • il impl駑ente des classes de stockage
  • il permet de faire du relationnel
  • il permet d'utiliser vos propres classes

III. Fonctionnement global

PMO traite le r駸ultat du SGBD de la fa輟n suivante: Il transforme chaque ligne r駸ultat de la requ黎e SQL en objets.
exemple avec une table utilisateur contenant 10 utilisateurs

			SELECT * from utilisateur;
			va renvoyer 10 objets utilisateur.
			
exemple avec une table utilisateur contenant 10 utilisateurs, une table ville contenant 5 villes

			SELECT * from utilisateur,ville WHERE utilisateur.id_ville=ville.id_ville;
			va renvoyer 10 objets utilisateur, et 5 objets ville
			

IV. Le controlleur PMO_MyController

L'objet PMO_MyController sert ? executer une requ黎e SQL.
Executer une requ黎e SQL

			$controller = New PMO_MyController();
			$map = $controller->query("SELECT*FROMutilisateur,ville;");
			while($result = $map->fetch()){
				echo $result['ville']->nom;
				echo $result['utilisateur']->nom;
			}
			

V. Les objets PMO_MyObject

PMO cr馥 des objets de type PMO_MyObject.

PMO_MyObject poss鐡e trois propri騁駸:

  • object_id : identifiant unique de l'objet (obsol鑼e)
  • object_table : une r馭駻ence qui pointe vers un objet PMO_MyTable d馗rivant le sch駑a de la table dont d馗oule l'objet
  • object_attribute : un tableau index? contenant vos donn馥s, nom de colonne => valeur
PMO_MyObject poss鐡e plusieurs m騁hodes:

  • ::factory(nomdetable) : sert ? cr馥r un objet PMO_MyObject vide conforme au sch駑a de la table pour insertion
  • ::override(nomdetable) : sert ? cr馥r un objet PMO_MyObject vide conforme au sch駑a de la table pour update (par d馭aut tout les attributs sont ? blanc - !attention aux pertes de donn馥s!)
  • load() : charge un objet depuis la base de donn馥s (les champs 駲uivalents ? la clef primaire doivent 黎re renseign駸)
  • delete() : supprimer l'objet de la base de donn馥s ce qui correspond ? 1 ligne dans une table
  • commit() : 馗rire ou mettre ? jour l'objet de la base de donn馥 ce qui correspond ? 1 ligne dans une table
  • toXml() : renvoit l'objet sous la forme d'un fichier XML
  • getTable() : renvoit la r馭駻ence de l'objet PMO_MyTable duquel il d馗oule.
  • getRelated() : renvoit une map contenant tous les objets li駸 1:n ? cet objet.
Afficher la valeur de l'attribut

			echo $objet->attribut;
			exemple:
			echo $utilisateur->login;
			
Modifier la valeur de l'attribut

			$objet->attribut = $valeur;
			Exemple:
			$utilisateur->login = "newlogin";
			
Charger un objet depuis la BDD

			$objet->load();
			Exemple pour l'utilisateur1:
/**creationd'un objet 駲uivalent ? la table utilisateur */
			$utilisateur = PMO_MyObject::factory('utilisateur');
			/**user_idcorrespond?laclefprimaire*/
			$utilisateur->user_id = 1;
			$utilisateur->load();
			
Enregistrer un objet en BDD

			$objet->commit();
			exemple:
			$utilisateur->commit();
			
Supprimer un objet de la BDD

			$objet->delete();
			
			exemple:
			$utilisateur->delete();
			
R馗up駻er un objet au format XML

			$objet->toXml($encoding);
			
			exemple:
			$utilisateur->toXml("ISO-8859-1");
			

VI. Les objets PMO_MyTable

Un objet PMO_MyTable d馗rit le sch駑a d'une table de la base de donn馥.

  • table_name : nom de la table
  • table_pk : array contenant le nom de toutes les clefs primaires
  • table_attribute : un tableau index? d'attributs contenant le nom de la colonne / Null/ type / default / extra => valeur
Retrouver l'objet table li? ? un objet PMO_MyObject

			$objetable = $objet->getTable()
			
			exemple:
			$tableutilisateur = $utilisateur->getTable();
			
Modifier le nom d'une colonne

			Editez la variable table_alias du cache de la table
			
			exemple pour que customer_id devienne toto:
				protected $table_alias = Array(
				'customer_id'=> 'toto'
				);
			
Utiliser votre propre classe impl駑entant PMO_MyObject pour cette table

			Editez la variable table_classname du cache de la table
			
			exemple:
			protected $table_classname = "newclassname";
			
Les objets PMO_MyTable sont 馗rit en cache ? la premi鑽e execution de votre script dans le r駱ertoire cache/


VI. Les maps PMO_MyMap

PMO r馭駻ence les objets PMO_MyObject dans un objet PMO_MyMap qui poss鐡ent des m騁hodes pour retrouver ces objets.
La structure de la propri騁? map

			PMO_MyMap -|
				 |-- row --|
							|--> r馭駻ence PMO_MyObject
				 
			
Exemple avec une table utilisateur et ville

			SELECT * from utilisateur,ville WHERE utilisateur.id_ville=ville.id_ville; 
			
			qui renverait deux lignes serait repr駸ent? comme 軋:
			
			PMO_MyMap -|
						|-- row 0 --|
				 |--> r馭駻ence PMO_MyObject utilisateur
 				 |--> r馭駻ence PMO_MyObject ville
						|-- row 1 --|
				 |--> r馭駻ence PMO_MyObject utilisateur
 				 |--> r馭駻ence PMO_MyObject ville
				 
			
Chaque Row permet d'identifier les relations entre les objets. Ainsi on sait que les objets du row 0 sont li駸 ensemble.

PMO_MyMap contient une propri騁? : un array index?

Les m騁hodes de PMO_MyMap:

  • getObjectByValue(nom de la table de l'objet, nom de l'attribut, valeur de l'attribut): permet de retrouver un objet dans la map grace ? la valeur d'un de ses attributs.
  • getMapByTable(nom de la table): permet de renvoyer une nouvelle sous map MyMap qui ne contient que des objets de la table pass? en param鑼re. C'est une forme de filtre.
  • getMapByValue(nom de la table de l'objet, nom de l'attribut, valeur de l'attribut): permet de renvoyer une nouvelle map qui ne contient que les lignes de r駸ultats contenant l'objet que l'on passe en param鑼re.
  • getMap(): retourne la propri騁? map
R馗up駻er ligne par ligne la map

			$result = $map->fetch();
			
			exemple:
			while($result = $map->fetch()){
				echo($result['utilisateur']->login);
			}
			
Retrouver un objet

			$object = $map->getObjectByValue("nomdetable", "nomdecolonne", "valeur");
			exemple:
			$object = $map->getObjectByValue("utilisateur", "login", "toto");
			
Cr馥r une autre map ne contenant que des objets provenant d'une table x

			$newmap = $map->getMapByTable("nomdelatable")
			exemple:
			$newmap = $map->getMapByTable("utilisateur");
			
Cr馥r une map ne contenant que des objets relatifs ? un objet dont la colonne x ? cette valeur

			$newmap = $map->getMapByValue("nomdetable", "nomdecolonne", "valeur");
			
			exemple:
			$newmap = $map->getMapByValue("utilisateur", "login", "toto");
			
Cr馥r une map ne contenant que des objets relatifs ? un objet dont ses n primary key ont ces valeurs

			$newmap = $map->getMapByObjectByValue($PMO_MyObject);
			
			exemple:
			$user->user_id = 1;
			$user->user_departement_id = 1;
			$newmap = $map->getMapByObjectByValue($user);
			
Cr馥r une map ne contenant que des objets relatifs ? un objet PMO_MyObject

			$newmap = $map->getMapRelated($PMO_object);
			
			exemple:
			$film->titre = 'tarzan';
			$newmap = $map-> getMapRelated($film);
			while ($result = $newmap->fetch())
				echo $result['salle']->numero;
				echo $result['cinema']->nom;
			

VIII. Le class loader

Le class loader permet d'utiliser vos propres objets h駻itant de PMO_MyObject, pour cela vous devez cr馥r une class dans le r駱ertoire class_loader/. Le nom du fichier doit 黎re class_xxxxx.php
exemple de class utilisateur impl駑entant une m騁hode helloworld()

			classutilisateur extends PMO_MyObject{
				public function helloworld(){
					echo('thisclassisinstanciatewhenadatabasetableuserexist');
				}
			}
		
Il faut ensuite 馘iter la classe PMO_MyTable_xxx.php se trouvant dans le r駱ertoire cache/ qui d馗rit la structure de votre table. Cette classe est cr馥 automatiquement par PMO dans ce r駱ertoire lors de la premi鑽e execution d'un SELECT par le controlleur.
exemple de modification de PMO_MyTable_xxx.php

			Editez cette ligne:
			protected $table_classname = "utilisateur";
		
Par d馭aut $table_classname vaut NULL ce qui signifie que vous utilisez pour toutes vos tables, l'objet g駭駻ique PMO_MyObject
appel de la m騁hode helloword
			
			L'objetpeut黎reensuiteutilis?decettefa輟n:
$object=PMO_MyObject::factory('utilisateur');
$object->helloworld();


IX. Les Exceptions

Pmo permet d'utiliser les exceptions pour les op駻ations sur les objets.
exemple de gestion exception

			try{
				$object->commit()
			}catch(Exception $e){
				die($e->getMessage());
			}
			
exemple de gestion exception

			try{
				$user->loginz = "toto";
			}catch(Exception $e){
				die($e->getMessage());
			}
			

X. Exemples

Pour les exemples, j'utiliserais une table employe, mais 軋 fonctionne pareil avec n'importe laquelle de vos tables

D騷ippez l'archive de PhpMyObject, et configurez le fichier config.php pour que PMO puisse int駻roger votre base de donn馥.

			/** mysql / sqlite / oracle / pgsql */
			$driverz = "sqlite";
	
			/** if you use sqlite */
			$dsn = 'sqlite:c:/test/test.db';	
	
			$hostz = 'localhost';
			$userz = 'votrelogin';
			$passz = 'votrepass';
			$basez = 'votrebase';
			
Affichage du nom des 20 premiers employ駸 de la table employe.

			require_once("core/PMO_MyController.php");
			
			$controler = new PMO_MyController();
			$map = $controler->query("SELECT*FROMemployelimit20;");
			
			while ($result = $map->fetch()){
				echo($result['employe']->nom);
			}
		
Affichage du nom des 20 premiers employ駸 de la table employe et du num駻o de leur place de parking.

			require_once("core/PMO_MyController.php");
			
			$controler = new PMO_MyController();
			$map = $controler->query("SELECT*FROMemploye,parkingWHEREemploye.id_employe=parking.id_employelimit20;");
			
			while ($result = $map->fetch()){
				echo($result['employe']->nom);
				echo($result['parking']->numero_place);
			}
		
Modification du nom de l'employe dupont en durand

			require_once("core/PMO_MyController.php");
			
			$controler = new PMO_MyController();
			$map = $controler->query("SELECT*FROMemploye;");
			
			$employe = $map->getObjectByValue("employe", "nom", "dupont");
			$employe->nom = "durand";
			$employe->commit();
		
Autre exemple si vous connaissez d駛? toutes les informations de Durand, il est inutile d'utiliser le controller. Attention aux pertes de donn馥s, override() initialise ? blanc toutes les colonnes qui n'ont pas 騁? param黎r馥s.

			require_once("core/PMO_MyController.php");
			
			$employe = PMO_MyObject::override("employe");
			$employe->id = "250";
			$employe->nom = "durand";
			$employe->commit();
		
Cr饌tion d'un objet employe qui a pour nom de Masson

			require_once("core/PMO_MyController.php");
			
			$employe = PMO_MyObject::factory("employe");
			$employe->nom = "Masson";
			$employe->commit();
		
Affichage de tous les noms d'un film dans lequel a jou? un acteur Dupont. Pour l'exemple, nous ne pr馗iserons pas ce crit鑽e directement dans la requ黎e SQL, mais nous utiliserons les relations PMO entre objets.

			require_once("core/PMO_MyController.php");
			
			$controler = new PMO_MyController();
			$map = $controler->query("SELECT*FROMfilm,actorWHEREfilm.actor_id=actor.actor_id;");
			
			$actor = $map->getObjectByValue("actor", "nom", "dupont");
			
			//nousr馗up駻onslamapdefilmli??l'acteurs駘ectionn?ci-dessus
			$mapoffilm = $actor->getRelated('film');
			while ($result = $mapoffilm->fetch()){
				echo($result['film']->nom_film);
			}
		

XI. Exemple de controleurs

exemple d'un controleur d騅elopp? avec PMO
			
			require_once("core/PMO_MyController.php");
						
			classgestionutilisateur(){
					
					/**r馗up鑽eunutilisateurdansSGBD*/
					public function getUser(PMO_MyObject $user){
						/**chargelesdonn馥s?partirdusgbd*/
						$user->load();
						
						/**retournel'objetuser*/
						return $user;
					}
						
					/**ajouteunutilisateurenbase*/
					public addUser(PMO_MyObject $user){
						/**ecritlesdonn馥sdel'objetdanslatableutilisateur*/
						$user->commit();
					}
					
					
					/**creerunobjetutilisateur*/
					public createUser(){
						return PMO_MyObject::factory("utilisateur");
					}
					
					/**supprimeunutilisateur*/
					public removeUser(PMO_Object $user){
						/**supprimelesdonn馥srelative?l'objetdanslatableutilisateur*/
						$user->delete();
					}
					/**affichelesdonn馥sutilisateurs*/
					public printUser(PMO_Object $user){
						echo($user->user_id);
						echo($user->name);
						echo($user->login);
					}
			
					/**controlelemotdepassedel'utilisateur*/
					public checkPass(PMO_Object $user, $password){
						if($user->pass == sha1($password))
							return TRUE;
							
						return FALSE;
					}		
			}
			
exemple d'un code imp駻atif utilisant PMO
			
			require_once("core/PMO_MyController.php");		
			
			/**instancielecontrolleur*/
			$controler = new PMO_MyController();
			/**creeunemapd'objets*/
			$map = $controler->query("SELECT*FROMuser,villewhereuser_id="$userid
			AND ville.id_ville=user .id_ville; ");

while($result=$map->fetchMap()){
$utilisateur=$result['user'];
$ville=$result['ville'];

echo("Nom:".$utilisateur->nom);
echo("Ville:"$ville->nom_ville);
}


XII. Remerciements

Remerciements ? Etanne pour la correction du manuel.



???????????? ? Version PDF (Miroir) ? Version hors-ligne (Miroir)

Valid XHTML 1.1! Valid CSS!

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 29/07/2007 Nicolas BOITEUX. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

AltStyle によって変換されたページ (->オリジナル) /