IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

[POO] associer base de données et classe


Sujet :

Langage PHP

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 39
    Points : 63
    Points
    63
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    Article(id, titre, contenu)
    Ma classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  2. #2
    Membre chevronné
    Avatar de ska_root
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2005
    Messages
    1 203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France

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

    Informations forums :
    Inscription : Août 2005
    Messages : 1 203
    Points : 1 839
    Points
    1 839
    Par défaut
    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.



  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 39
    Points : 63
    Points
    63
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 ?

  4. #4
    Membre chevronné
    Avatar de ska_root
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2005
    Messages
    1 203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France

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

    Informations forums :
    Inscription : Août 2005
    Messages : 1 203
    Points : 1 839
    Points
    1 839
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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...


  5. #5
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  6. #6
    Membre régulier
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations forums :
    Inscription : Juillet 2008
    Messages : 36
    Points : 99
    Points
    99
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  7. #7
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    jonoz à tap tap tapoté avec ses mimines
    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.

  8. #8
    Membre régulier
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations forums :
    Inscription : Juillet 2008
    Messages : 36
    Points : 99
    Points
    99
    Par défaut
    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"...).

  9. #9
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    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.

  10. #10
    Membre régulier
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations forums :
    Inscription : Juillet 2008
    Messages : 36
    Points : 99
    Points
    99
    Par défaut
    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.

  11. #11
    Membre émérite
    Avatar de gene69
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 769
    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 : 1 769
    Points : 2 446
    Points
    2 446
    Par défaut
    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.
    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.

  12. #12
    Membre chevronné
    Avatar de ska_root
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2005
    Messages
    1 203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France

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

    Informations forums :
    Inscription : Août 2005
    Messages : 1 203
    Points : 1 839
    Points
    1 839
    Par défaut
    Je pense qu'il voulait plutôt parler de polymorphisme du constructeur que de surcharge...


  13. #13
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    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.

  14. #14
    Membre habitué
    Homme Profil pro
    Inscrit en
    Juillet 2010
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 96
    Points : 140
    Points
    140
    Par défaut
    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.

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 39
    Points : 63
    Points
    63
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

Discussions similaires

  1. POO et base de données incompréhension
    Par hideadlock dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 11/04/2013, 11h44
  2. Base de données et classe PreparedStatement
    Par bandit_debutant dans le forum Débuter avec Java
    Réponses: 11
    Dernier message: 06/06/2008, 13h49
  3. formulaire / php / base de données et classes
    Par No3l_tek dans le forum Langage
    Réponses: 1
    Dernier message: 30/04/2008, 10h52
  4. POO et bases de données
    Par szdavid dans le forum Langages de programmation
    Réponses: 3
    Dernier message: 24/01/2006, 16h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo