Précédent   Forum des professionnels en informatique > PHP > Langage > Syntaxe
Syntaxe Forum d'entraide sur la syntaxe de PHP et la POO. Avant de poster -> FAQ syntaxe, Cours d'initiation et cours de POO
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 11/01/2011, 21h29   #1
Invité de passage
 
Inscription : avril 2010
Messages : 15
Détails du profil
Informations forums :
Inscription : avril 2010
Messages : 15
Points : 4
Points : 4
Par défaut [POO] associer base de données et classe

Bonjour,

Je commence la programmation orientée objet en PHP avec utilisation d'une base de données. Cependant, je ne sais pas si ma manière d'aborder le problème est correcte en ce qui concerne la façon de gérer les échanges avec la base de données.

Je vais prendre un exemple simplifié volontairement.

Ma base de données :
Code :
Article(id, titre, contenu)
Ma classe :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Article
{
	private $id;
	private $titre;
	private $contenu;
 
	function __construct($id)
	{
		// je construis mon objet en faisant une requête dans ma base de données
		// puis en affectant les résultats de la requête aux champs de mon objet
		$this->id = $id;
		$this->titre = $mesDonnes->titre;
		$this->contenu = $mesDonnees->contenu;
	}
 
	/* accesseurs */
	/* mutateurs */
 
	public miseAJourSql()
	{
		// mise à jour de mon objet dans la base de données en fonction de la valeur des attributs de l'objet instancié
		mysql_query('UPDATE article SET titre="'.$this->titre.'", contenu="'.$this->contenu.'" WHERE id='.$this->id);
	}
 
	/* Méthodes statiques */
	public static function supprimerSql($unId)
	{
		// suppression de l'id passé en paramètre dans ma base de données
	}
	public static function getLesArticles()
	{
		// effectue une requête dans la base de données
		// puis retourne une collection d'articles
	}
}
Pour la suppression ou la liste d'artilces, j'utilise une méthode statique vu qu'il n'est pas nécessaire d'instancier d'objet.

Ce mode de fonctionnement est-il "correct", mauvais ou à améliorer ?
Avez-vous de meilleures façon de faire à me conseiller ?

Merci d'avance pour votre aide
floriann est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/01/2011, 21h53   #2
Membre Expert
 
Avatar de ska_root
 
Homme
Développeur informatique
Inscription : août 2005
Messages : 1 179
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 42
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : Service public

Informations forums :
Inscription : août 2005
Messages : 1 179
Points : 1 580
Points : 1 580
Bonjour,

j'y ajouterais au minimum des contrôles sur les données, une protection de type htmlspecialchars ou autre. J'imagine que tu le fais dans les mutateurs...

Un nommage des méthodes génériques plus explicite et/ou conventionnel :

article->create(), article->update(), article->delete(), article->getAll()....

et surtout une gestion des exceptions...

tu instancies la classe avec un ID, dans ce cas, tu ne vises pas la possibilité de créer un nouvel enregistrement. j'aurais mis une valeur par défaut au paramètre de manière à tester sa valeur et détecter une création... ou alors testes au moins son existence avant de tenter d'aller chercher son contenu en base.


__________________
http://cdemarche.developpez.com/

Tu as la réponse à ta question ? N'oublies pas le petit en bas à gauche de ton message...
ska_root est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/01/2011, 22h22   #3
Invité de passage
 
Inscription : avril 2010
Messages : 15
Détails du profil
Informations forums :
Inscription : avril 2010
Messages : 15
Points : 4
Points : 4
Citation:
Envoyé par ska_root Voir le message
Bonjour,

j'y ajouterais au minimum des contrôles sur les données, une protection de type htmlspecialchars ou autre. J'imagine que tu le fais dans les mutateurs...

Un nommage des méthodes génériques plus explicite et/ou conventionnel :

article->create(), article->update(), article->delete(), article->getAll()....

et surtout une gestion des exceptions...

tu instancies la classe avec un ID, dans ce cas, tu ne vises pas la possibilité de créer un nouvel enregistrement. j'aurais mis une valeur par défaut au paramètre de manière à tester sa valeur et détecter une création... ou alors testes au moins son existence avant de tenter d'aller chercher son contenu en base.


Merci pour ta réponse ska_root. Pour les contrôles et protections, rassure-toi ils sont faits (d'ailleurs je suis passé sous PDO et requêtes préparées ). C'est juste que j'ai refait une classe d'exemple ici de mémoire (je n'ai pas ma classe sur moi).

Tu fais bien d'aborder l'histoire du nouvel enregistrement : je voulais au départ faire de la surcharge de constructeur, mais je me suis retrouvé face à une erreur fatale et j'ai constaté qu'il n'était apparemment pas possible d'en faire en PHP

Au final, j'ai procédé comme tel (toujours de mémoire et simplifié) :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
 
function __construct($id, $titre = '', $contenu = '')
{
	if($id != 0)
	{
		// création depuis la bdd
	}
	else
	{
		// affectation des champs depuis les paramètres
	}
}
Sinon, à part ces éléments, la démarche est correcte en ce qui concerne les accès (insert, update, getAll en statique...) à la base de données ?
floriann est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/01/2011, 23h24   #4
Membre Expert
 
Avatar de ska_root
 
Homme
Développeur informatique
Inscription : août 2005
Messages : 1 179
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 42
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : Service public

Informations forums :
Inscription : août 2005
Messages : 1 179
Points : 1 580
Points : 1 580
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 
<?php
 
class Article {
 
 
	public $title="";
	public $contenu="";
	public $id="";
 
	public function __construct($id=0, $title="", $contenu="") {
		$this->title= $title;
		$this->contenu= $contenu;
		$this->id= $id;
	}
 
	public function getMethod() {
		if(!$this->id) echo "Article :: Creation d'un nouvel article";
		else echo "Article :: Modification de l'article ".$this->id;
	}
 
}
 
// creation
echo "<h3>Creation</h3>";
$article = new Article();
$article->getMethod();
 
echo "<hr/>";
echo "<h3>Modification</h3>";
$article= new Article(222);
$article->getMethod();
 
?>
sinon oui, la méthode peut-être statique pour le getAll et pourquoi pas le delete...

__________________
http://cdemarche.developpez.com/

Tu as la réponse à ta question ? N'oublies pas le petit en bas à gauche de ton message...
ska_root est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/01/2011, 10h31   #5
Expert Confirmé
 
Avatar de rawsrc
 
Homme Martin
Dev indep
Inscription : mars 2004
Messages : 1 461
Détails du profil
Informations personnelles :
Nom : Homme Martin
Âge : 35
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Dev indep

Informations forums :
Inscription : mars 2004
Messages : 1 461
Points : 2 548
Points : 2 548
Envoyer un message via Skype™ à rawsrc
Bonjour,

Comme le dit ska_root toutes les méthodes d'accès/extraction de données peuvent être statiques.
En extraction (SELECT), tu récupères généralement un tableau, en accès (INSERT, UPDATE, DELETE) tu récupères généralement soit un boolean soit un integer. Donc le corps de ta classe peut se résumer à
Code :
1
2
3
4
5
6
class Article {
   static function insert(array $p) { }
   static function update(array $p) { }
   static function delete($pId) { }
   static function select(array $pWhere) { }
}
et les appels à
Code :
Article::insert($p); ...
Enfin ceci n'est qu'un exemple pour te montrer que l'accès aux données peut ne dépendre d'aucune instance de classe
rawsrc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/01/2011, 12h07   #6
Membre régulier
 
Inscription : juillet 2008
Messages : 35
Détails du profil
Informations forums :
Inscription : juillet 2008
Messages : 35
Points : 76
Points : 76
Ca reste quand même une bonne idée d'instancier les objets pour effectuer des actions ayant trait à la persistance.

L'utilisation de méthodes statiques est en général plutôt utilisée quand on a une classe "enregistreuse" séparée, qui a par exemple une méthode :
Code :
1
2
3
4
 
 public static function delete(MyObject $object){
    //code qui effectue la suppression
 }
En effet, l'id dans l'absolu est juste un nombre, il ne prend son sens métier qu'au sein d'une instance.

L'exception est le cas où nous avons vraiment besoin de limiter au minimum nécessaire les instanciations. Je n'ai jamais rencontré un cas avec suffisamment de données pour que ce soit significatif en php.
jonoz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/01/2011, 15h15   #7
Expert Confirmé
 
Avatar de rawsrc
 
Homme Martin
Dev indep
Inscription : mars 2004
Messages : 1 461
Détails du profil
Informations personnelles :
Nom : Homme Martin
Âge : 35
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Dev indep

Informations forums :
Inscription : mars 2004
Messages : 1 461
Points : 2 548
Points : 2 548
Envoyer un message via Skype™ à rawsrc
jonoz à tap tap tapoté avec ses mimines
Citation:
En effet, l'id dans l'absolu est juste un nombre, il ne prend son sens métier qu'au sein d'une instance.
Enfin pas obligatoirement, dans le cas où tu utilises des méthodes statiques dans les classes pour accéder aux données, le sens de l'id est donné par la classe manipulée.
Quand tu faisLe sens de l'id tu l'as déjà par la classe Article. Tu sais de fait que l'id correspond à l'id d'un article, pas besoin d'instance dans ce cas et tu n'es pas perdu non plus.
rawsrc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/01/2011, 16h01   #8
Membre régulier
 
Inscription : juillet 2008
Messages : 35
Détails du profil
Informations forums :
Inscription : juillet 2008
Messages : 35
Points : 76
Points : 76
Le truc c'est que souvent une suppression c'est pas juste une ligne en moins dans la DB.

Tu vas procéder à des vérifications métier ou avoir des contraintes. Dans ce cas, tu vas de toutes façons instancier ton objet pour traiter ces questions (dans le cas des contraintes, tu peux laisser le SGBD s'en charger mais c'est un peu dangereux non ?) donc autant t'en servir pour faire les suppressions.

Tu ne veux pas supprimer une ligne dans la DB, tu veux supprimer un objet, une entité métier. Du coup, autant manipuler une vraie entité métier, ça nous permet de tirer avantage de la POO.

Le statique c'est quand même un monde à part, en php, ça permet en gros de s'affranchir de certaines contraintes de la POO. Les cas où c'est vraiment pertinent ne sont pas légion, notamment au niveau des objets métier. On s'en sert surtout au niveau des objets techniques (ex: Singleton DB - bien que discutable -, Factory et dérivés, "savers"...).
jonoz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/01/2011, 19h45   #9
Expert Confirmé
 
Avatar de rawsrc
 
Homme Martin
Dev indep
Inscription : mars 2004
Messages : 1 461
Détails du profil
Informations personnelles :
Nom : Homme Martin
Âge : 35
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Dev indep

Informations forums :
Inscription : mars 2004
Messages : 1 461
Points : 2 548
Points : 2 548
Envoyer un message via Skype™ à rawsrc
Je peux t'assurer que la quasi totalité des objets métiers peuvent être développés en static. L'idée c'est de ne jamais manipuler un enregistrement comme un objet mais comme un tableau ou un scalaire.
Ton modèle sera segmenté en Article:: Catalogue:: Fournisseur::... Une fois posé, le modèle est totalemennt statique, par contre les données qu'il devra manipuler elles sont dynamiques.

Effectivement, tu peux très bien utiliser des instances pour tout mais parfois cela n'est pas nécessaire. Bref comme toujours en informatique il y a plusieurs voies pour atteindre le même résultat.
rawsrc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/01/2011, 00h36   #10
Membre régulier
 
Inscription : juillet 2008
Messages : 35
Détails du profil
Informations forums :
Inscription : juillet 2008
Messages : 35
Points : 76
Points : 76
La question n'est pas de savoir si on peut le faire, mais plutôt si c'est pertinent de le faire.

Quel est l'avantage concret d'utiliser du statique pour persister des objets métiers qui sont en général peu volumineux ?

En fait, j'ai le point de vue inverse au tien : il faut utiliser du statique quand c'est nécessaire et tant que possible s'en tenir à des instances.

Une des raisons qui me font penser ainsi est l'utilisation de Template Methods. Par exemple, une requête de création et une requête de mise à jour ont une grande partie commune. Du coup, en statique, tu écris trois méthodes statiques, et tu multiplies donc les appels statiques, ce qui revient dans les grandes lignes à faire du procédural...Je ne parle même pas des cas où il faut contrôler et valider les données (en gros, tous les cas...).

A mon sens, le design de l'application est moins cohérent dans le sens où il s'appuie alors sur des objets techniques là où l'usage d'objets métier est à privilégier; le cas le plus désagréable étant celui où des objets métier ont quelques méthodes ou attributs statiques, ça devient juste un gros fouilli.

En tout état de cause, l'intérêt de la POO est justement de manipuler autant que possible des types complexes, et non des scalaires ou des tableaux.
jonoz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/01/2011, 00h49   #11
Membre Expert
 
Avatar de gene69
 
Inscription : janvier 2006
Messages : 951
Détails du profil
Informations personnelles :
Localisation : France

Informations professionnelles :
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : janvier 2006
Messages : 951
Points : 1 063
Points : 1 063
pendant longtemps j'ai utiliser les methodes statiques uniquement parce que les classes permettent de trier les fonctions par theme, je faisais des classes sans constructeurs et sans attribut. c'est pratique et en plus on a l'autochargement des classes qui fonctionne.

c'est le grand détournement des classes par le statiques.

digression faite je relève ceci.
Citation:
je voulais au départ faire de la surcharge de constructeur, mais je me suis retrouvé face à une erreur fatale et j'ai constaté qu'il n'était apparemment pas possible d'en faire en PHP
c'est faux.
c'est faux.
c'est faux.
la preuve c'est que tu peux utiliser parent.
en php4 c'était déjà possible mais c'était tordu comme syntaxe.
si tu utilises php 5.3 tu vas même avoir une gestion assez fine de la surchage de n'importe quelle méthode meme en statique.
__________________
PHP fait nativement la validation d'adresse électronique Vous êtes perdu en PHP? rassurez-vous ici (en)
Utilisez le bouton résolu!
gene69 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/01/2011, 06h43   #12
Membre Expert
 
Avatar de ska_root
 
Homme
Développeur informatique
Inscription : août 2005
Messages : 1 179
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 42
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : Service public

Informations forums :
Inscription : août 2005
Messages : 1 179
Points : 1 580
Points : 1 580
Je pense qu'il voulait plutôt parler de polymorphisme du constructeur que de surcharge...

__________________
http://cdemarche.developpez.com/

Tu as la réponse à ta question ? N'oublies pas le petit en bas à gauche de ton message...
ska_root est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/01/2011, 22h35   #13
Expert Confirmé
 
Avatar de rawsrc
 
Homme Martin
Dev indep
Inscription : mars 2004
Messages : 1 461
Détails du profil
Informations personnelles :
Nom : Homme Martin
Âge : 35
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Dev indep

Informations forums :
Inscription : mars 2004
Messages : 1 461
Points : 2 548
Points : 2 548
Envoyer un message via Skype™ à rawsrc
Bonsoir,

@jonoz : moi je dirais plutôt :
il faut utiliser du statique tant que possible et s'en tenir à des instances quand cela est nécessaire.

Je le répète : le modèle une fois posé est statique, il ne fait que manipuler des données dynamiques. Donc les interactions dans le modèle sont statiques. Et au pire il est toujours possible d'utiliser des instances d'objets pour manipuler les tableaux et autres élements dynamiques.

Personnellement, je développe toujours mes modèles en statique et je n'ai aucune difficulté quant à la modélisation d'élements complexes.

Par contre pour ce qui est des vues, tout est géré sous forme d'instance de classe.
rawsrc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/01/2011, 07h26   #14
Membre du Club
 
Jean Frederic Nault
Inscription : juillet 2010
Messages : 61
Détails du profil
Informations personnelles :
Nom : Jean Frederic Nault

Informations forums :
Inscription : juillet 2010
Messages : 61
Points : 59
Points : 59
Citation:
Envoyé par floriann Voir le message
Je commence la programmation orientée objet en PHP avec utilisation d'une base de données. Cependant, je ne sais pas si ma manière d'aborder le problème est correcte en ce qui concerne la façon de gérer les échanges avec la base de données.
Salut Florian,

la methode delete peut etre static dépendamment du contexte, mais avant d'y penser je te conseillerais de lire un peu sur le dao pattern.

Comme tu dit, tu commence a faire de la poo, et pour un début cest assez bien, tu as penser a diviser le read(getLesArticles), write(oups...), delete(supprimerSql) update(miseAJourSql)

Si tu détermine/précise, en debut de class, la structure de ton objet

ex : var property = array(ID,titre,text...), un dao pattern sert a mapper cest dite valeur pour de façons generique creer en autre le read write del...

il y a plusieur tuto sur le net sur le sujet, par la suite tu pourrais aussi séparer ton sql de ton objet au moyen dune class database tel pdo par exemple qui permet de faire de lactive record, un autre design pattern tres utilise.
nault est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/01/2011, 13h19   #15
Invité de passage
 
Inscription : avril 2010
Messages : 15
Détails du profil
Informations forums :
Inscription : avril 2010
Messages : 15
Points : 4
Points : 4
Bonjour à vous,

Merci pour toutes vos réponses.

@ Xysyo et jonoz :
Je me rappelle être une fois tombé sur un programme où le mode de fonctionnement me surprenait, avec des choses du genre :
Code :
1
2
$maClasse = new MaClasse();
$maClasse->delete();
Avec comme seule utilisation de la méthode de suppression ; d'où mon idée de passer ça en statique vu que l'instanciation me semblait alors inutile.

@ gene69 :
Je faisais bien référence à la notion de surcharge de constructeur.

Exemple :
Code :
1
2
3
4
5
6
7
8
9
10
11
class MaClasse
{
      function __construct($id)
      {
            // construction de ma classe depuis la bdd
      }
      function __construct($champ1, $champ2, $champ2)
      {
            // construction de ma classe à partir des paramètres
      }
}
Le code ci-dessus n'est pas accepté par PHP. Y a peut-être une autre méthode ?

@ nault :
Je vais me documenter sur cela, merci
floriann est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 19h48.


 
 
 
 
Partenaires

Hébergement Web