Mes débuts en POO

Mes débuts en POO - PHP - Programmation

Marsh Posté le 21-06-2008 à 02:20:01    

Salut tout le monde,
je suis en train de passer à la POO en PHP, et je dois avouer que j'ai beaucoup de mal.
 
Je vais donc tenir à jour ce topic avec mes différentes classes et questions en espérant que vous pourrez répondre à ces dernières et m'aider à mieux coder mes classes.
 
Je commence avec ma classe MySQL :

Code :
  1. Class Mysql implements Db {
  2.     
  3.     public function __construct($hostname, $username, $password, $dbname) {
  4.         
  5.         $connection = mysql_connect($hostname, $username, $password);
  6.         
  7.         if($connection) {
  8.             $db = mysql_select_db($dbname) or die(mysql_error());
  9.         }
  10.         
  11.     }
  12.     
  13.     public function query($res) {
  14.         
  15.         return $this->mysql_query($res);
  16.         
  17.     }
  18.     
  19. }


---------------
Twitter
Reply

Marsh Posté le 21-06-2008 à 02:20:01   

Reply

Marsh Posté le 21-06-2008 à 02:25:24    

[:drapal] J'ai aussi du mal avec la POO et vu que je projette de me mettre au C# [:cupra]


---------------
"I can cry like Roger. It's just a shame I can't play like him" - Andy Murray, 2010
Reply

Marsh Posté le 21-06-2008 à 03:36:49    

Aucun rapport avec la POO:  
*pourquoi ne pas choisir dès le départ mysqli ou PDO?
*l'échappement des données sera faite où et comment?
*conclusion des 2 utilises au moins mysqli pour pouvoir utiliser les requêtes préparées quand c'est nécessaire bien entendu ;)
 
Petit conseil qu'on ne respecte jamais assez en php mais qui a son importance en objet surtout pour php5: bien déclarer tous les membres de ta classe avec la portée que tu veux leurs donner dès le départ. Sinon c'est de la portée publique. Pareil pour les détails pour mes méthodes avec le mot clé final si tu veux pas que ça puisse être redéfini.
En gros faut verrouiller au maxi vu que php permet des largesses.
 
NE pas oublier toutes les méthodes magiques utilisées à bon escient.

Reply

Marsh Posté le 21-06-2008 à 03:52:12    

Je n'utilise ni mysqli et ni PDO car ce n'est pas de base chez tous les hébergeurs, et ce que je suis en train de développer devra tourner chez tous les hébergeurs.


---------------
Twitter
Reply

Marsh Posté le 21-06-2008 à 08:21:33    

Alors renonce à utiliser la POO. Tous les hébérgeurs n'ont pas PHP5.
Et renonce aussi à faire toi même le script de connexion : Tous les hébérgeurs n'ont pas des machines suffisamment puissantes pour faire tourner une usine à gaz.
 
Non mais fait quand même arrêter les conneries hein? Pratiquement tous les hébérgeurs (en tous cas ceux serieux) proposent mysqli. En re-écrivant toi même "from scratch" cette lib, tu t'assures de mettre en place un truc immense, super lent et buggé

Reply

Marsh Posté le 21-06-2008 à 14:20:44    

Ok, va pour mysqli alors :jap:
Enfin, MySqli ou PDO ?


---------------
Twitter
Reply

Marsh Posté le 21-06-2008 à 14:46:36    

koskoz a écrit :

Je n'utilise ni mysqli et ni PDO car ce n'est pas de base chez tous les hébergeurs, et ce que je suis en train de développer devra tourner chez tous les hébergeurs.


PDO pas forcement mais mysqli un peu quand meme :o


---------------
« The enemy is the gramophone mind, whether or not one agrees with the record that is being played at the moment. » — George Orwell
Reply

Marsh Posté le 21-06-2008 à 15:50:12    

Je suis en train de regarder du côté de mysqli.
 
La première classe que j'aimerai développer est une classe de gestion d'affichage des news.
Donc, mon objet c'est ma news, ça on est d'accord, mais je ne vois pas quoi mettre dans mon constructeur, une requette qui récupère mes news ?


---------------
Twitter
Reply

Marsh Posté le 21-06-2008 à 16:35:55    

Tu dois résonner ainsi : exemple :
 
L'article est un objet.  
Que peut faire l'article ?
 
Il peut être créé ( $article = new Article(); ), charger ses attributs de classe en fonction d'un id ( $article->load($id); ), afficher son contenu ( $article->print(); ), ...etc.
 
Essaye de penser "délégation". Tu dois demander à tes objets de faire le boulot à ta place, tu dois leur donner des ordres ("Charge-toi !", "Affiche-toi !", ...etc.).


Message édité par CyberDenix le 21-06-2008 à 16:36:55

---------------
Directeur Technique (CTO)
Reply

Marsh Posté le 21-06-2008 à 16:51:24    

OK, je vois mieux, merci.


---------------
Twitter
Reply

Marsh Posté le 21-06-2008 à 16:51:24   

Reply

Marsh Posté le 21-06-2008 à 17:03:24    

Première chose quand on aborde la POO : surtout ne pas commencer par faire des classes de gestion de base de données, c'est le meilleur moyen de se casser la gueule. Les implications sont énormes (connexion persistente, échappement des données, abstraction vis-à-vis du SGBD sous-jacent, configuration, ect.).

 

Mieux vaut commencer par quelque chose de plus soft.


Message édité par FlorentG le 21-06-2008 à 17:03:37
Reply

Marsh Posté le 21-06-2008 à 17:27:00    

Une classe de gestion des news, ça te parait correct ?


---------------
Twitter
Reply

Marsh Posté le 21-06-2008 à 19:12:17    

Oui .. en tout cas c'est déjà plus leger :D

Reply

Marsh Posté le 22-06-2008 à 12:28:03    

surtout pourquoi reinventer la roue en voulant coder sa couche bdd :
http://www.phpdoctrine.org

Reply

Marsh Posté le 22-06-2008 à 17:10:48    

Voici ma class News pour l'instant.
Je ne sais pas du si je suis bien partie, et je ne vois toujours pas quoi mettre dans le constructeur.
 

Code :
  1. <?php
  2.  
  3. class News {
  4.     
  5.     function __construct() {
  6.         
  7.     }
  8.     
  9.     function see_news($nbr_news) {
  10.         $res = $mysqli->query("SELECT t1.*, t1.id AS news_id, t2.id, t2.pseudo, t3.id AS news_cat_id, t3.nom, t3.image
  11.                                 FROM ".TBL_NEWS." AS t1
  12.                                 INNER JOIN ".TBL_MEMBRES." AS t2 ON t1.auteur_id = t2.id
  13.                                 LEFT JOIN ".TBL_NEWS_CAT." AS t3 ON t1.cat_id = t3.id
  14.                                 ORDER BY t1.id
  15.                                 DESC LIMIT 3". $nbr_news);
  16.         
  17.         while($row = $res->fetch_assoc())
  18.         {
  19.             $row = array_map(stripslashes, $row);
  20.             
  21.             $this->news_id = $row['news_id'] ;
  22.             $this->cat_id = $row['cat_id'] ;
  23.             $this->cat_auteur = $row['cat_auteur'] ;
  24.             $this->titre = $row['titre'] ;
  25.             $this->intro = $row['intro'] ;
  26.             $this->news = $row['news'] ;
  27.             $this->date = $row['date'] ;
  28.             $this->membre_id = $row['membre_id'];
  29.             $this->pseudo = $row['pseudo'];
  30.             $this->news_cat_id = $row['news_cat_id'];
  31.             $this->nom_cat = $row['nom'];
  32.             $this->img_cat = $row['img'];
  33.         }
  34.         
  35.     }
  36.     
  37. }
  38.  
  39. ?>


---------------
Twitter
Reply

Marsh Posté le 22-06-2008 à 17:31:06    

Non.
- $mysqli c'est qui? Il est defini nulle part => Faux
- Tu fais un LIMIT 3.$nbr_news => T'es conscient que tu pourras afficher uniquement etre 30 et 39 news?  
- Tous les attributs (news_id & co) sont pas déclarés. C'est un sale truc que seul les langages permissifs comme PHP autorisent et qu'il faut pas utiliser. Ca ouvre la porte à plein de salopperies.
- Mettre un constructeur par défaut c'est pas d'une utilité flagrante je trouve .. mais ça je sais que certains le font quand même..
- J'espere que tu fais un contrôle rigoureux ailleurs sur le fait que $nbr_news est bien un entier ... Moi je préfère le faire directement dans la classe..

Reply

Marsh Posté le 22-06-2008 à 19:25:13    

Pourquoi ya un stripslashes sur les données sorties de la db? [:ciler]

 

Pourquoi ya tout le bordel concernant les catégories qui est stocké dans une news et pas dans un objet à part? [:ciler]

 

Idem pour l'auteur de la news? [:ciler]

 

Et surtout, pourquoi ya tout ce bordel de SQL, alors que ça devrait être dans un DAO/Manager séparé? [:ciler]

 

(et dans le constructeur, be faut tout ce qui est nécessaire à la création d'une news et qui ne peut être inférré séparément [:spamafote])


Message édité par masklinn le 22-06-2008 à 19:27:03

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 22-06-2008 à 19:37:32    

Ok, donc dans le constructeur c'est la création d'une news du côté admin c'est ça ?
 
Pour l'auteur et la catégorie de la news, je dois faire d'autres classes ?
Pour ce qui est du SQL, je vois pas du tout de quoi tu parles :/


---------------
Twitter
Reply

Marsh Posté le 22-06-2008 à 19:59:19    

La création d'une news en général
oui
http://butunclebob.com/ArticleS.Un [...] iplesOfOod premier lien (SRP - Single Responsibility Principle)


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 22-06-2008 à 22:33:18    

Bon, j'en suis à ça pour l'instant :
 

Code :
  1. <?php
  2. class newsController {
  3.     
  4.     var $news_id;
  5.     var $cat_id;
  6.     var $cat_auteur;
  7.     var $titre;
  8.     var $intro;
  9.     var $news;
  10.     var $date;    
  11.     
  12.     function __construct() {
  13.         
  14.     }
  15.     
  16.     function see_news($nbr_news) {
  17.         
  18.         while($row = $res->fetch_assoc())
  19.         {
  20.             $row = array_map(stripslashes, $row);
  21.             
  22.             $this->news_id = $row['news_id'] ;
  23.             $this->cat_id = $row['cat_id'] ;
  24.             $this->cat_auteur = $row['cat_auteur'] ;
  25.             $this->titre = $row['titre'] ;
  26.             $this->intro = $row['intro'] ;
  27.             $this->news = $row['news'] ;
  28.             $this->date = $row['date'] ;
  29.         }
  30.         
  31.     }
  32.     
  33. }
  34.  
  35. ?>


 

Code :
  1. <?php
  2. class newsModel {
  3.     function get_news($nbr_news) {
  4.         return $mysqli->query("SELECT t1.*, t1.id AS news_id, t2.id, t2.pseudo, t3.id AS news_cat_id, t3.nom, t3.image
  5.                                 FROM ".TBL_NEWS." AS t1
  6.                                 INNER JOIN ".TBL_MEMBRES." AS t2 ON t1.auteur_id = t2.id
  7.                                 LEFT JOIN ".TBL_NEWS_CAT." AS t3 ON t1.cat_id = t3.id
  8.                                 ORDER BY t1.id
  9.                                 DESC LIMIT 3". $nbr_news);
  10.     }
  11. }
  12. ?>


 
Faut-il que j'appelle la fonction "get_news" dans ma classe newsController où ça se fait encore ailleurs ?


---------------
Twitter
Reply

Marsh Posté le 23-06-2008 à 13:04:38    

ca ressemble a un debut de mvc ca non ?

Reply

Marsh Posté le 23-06-2008 à 13:09:37    

ta classe newModel pourrai bien s'appeler news tout court

 

dans le controleur, tu appelle une vue ( NewsView )  qui prends en paramètre news

 

et c'est dans la fonction qui fait l'affichage dans newsView que tu appelles News->get_news(10);


Message édité par flo850 le 23-06-2008 à 13:09:51

---------------

Reply

Marsh Posté le 23-06-2008 à 15:39:33    

Pour ton modèle, que veux-tu qu'il représente ?
Une news ou l'ensemble de tes news ?
 
Je pense qu'il serait logique qu'un objet news corresponde à une news, avec donc les méthodes :
- constructeur => crée un objet news en prenant en paramètre ses attributs
$n = new News('Titre', $auteur, ...);
ou mieux (à mon avis) :
$n = new News(Array('titre'=>'Titre', 'auteur'=>$auteur)); qui te permet de passer les arguments que tu veux
- save => enregistre la news dans la bdd
- delete => suppriem de la bdd
- accesseurs
 
Et ensuite des méthodes statiques :
- $n=News::find($id);
- $n=News::find('auteur'=>$auteur); => renvoie un tableau
- News::delete($id);
 
etc ...
 
A la limite, va voir http://api.rubyonrails.org/classes [...] /Base.html
C'est pas du PHP, mais ça donne une bonne idée de comment un modèle peut se comporter ...

Reply

Marsh Posté le 24-06-2008 à 20:27:36    

Avant de coder, tu devrais commencer par acquérir les bases de la poo. Un minimum de connaissances théoriques est nécessaire.

Reply

Marsh Posté le 25-06-2008 à 21:37:56    

petite question, pourquoi donc NewsModel peu s'apeler News tout court et pas NewsController alors que celu ci possede touts les attribut de la news en question ? (c'est une question a la con mais g beau essayer je galère avec le mvc... =)

Reply

Marsh Posté le 25-06-2008 à 21:40:28    

personnellement, j'ai tendance a penser que c'est le modèle "news" qui représente le mieux ce qu'ets une news  
 
le contrôleur représente les comportement que peut avoir cette news , et la vue son affichage


---------------

Reply

Marsh Posté le 29-06-2008 à 22:54:22    

Voilà où j'en suis maintenant :
 

Code :
  1. <?php
  2. class newsController {
  3.     
  4.     var $news_id;
  5.     var    $cat_id;
  6.     var $auteur_id;
  7.     var $titre;
  8.     var $intro;
  9.     var $contenu;
  10.     var $date;
  11.     
  12.     function __construct($titre, $intro, $contenu, $date, $auteur, $categorie) {
  13.         $this->titre = $titre;
  14.         $this->intro = $intro;
  15.         $this->contenu = $contenu;
  16.         $this->date = $date;
  17.         $this->auteur_id = $auteur;
  18.         $this->cat_id = $categorie;
  19.     }
  20.     
  21.     function save() {        
  22.         $add = insert($this->titre, $this->intro, $this->contenu, $this->date, $this->auteur_id, $this->cat_id);
  23.         if($add)
  24.             echo "L'ajout de la news s'est déroulé avec succès.";
  25.         else
  26.             echo "Une erreur est survenue.";
  27.     }
  28.     
  29.     function delete($news_id) {
  30.         $delete = delete($news_id);
  31.         if($delete)
  32.             echo "La suppression de la news s'est déroulée avec succès.";
  33.         else
  34.             echo "Une erreur est survenue.";
  35.     }
  36.     
  37. }
  38.  
  39. ?>


 

Code :
  1. <?php
  2. class news {
  3.     
  4.     function get_news($nbr_news) {
  5.         return $mysqli->query("SELECT t1.*, t1.id AS news_id, t2.id, t2.pseudo, t3.id AS news_cat_id, t3.nom, t3.image
  6.                                 FROM ".TBL_NEWS." AS t1
  7.                                 INNER JOIN ".TBL_MEMBRES." AS t2 ON t1.auteur_id = t2.id
  8.                                 LEFT JOIN ".TBL_NEWS_CAT." AS t3 ON t1.cat_id = t3.id
  9.                                 ORDER BY t1.id
  10.                                 DESC LIMIT 3". $nbr_news);
  11.     }
  12.     
  13.     function insert($titre, $intro, $contenu, $date, $auteur_id, $cat_id) {
  14.         return $mysqli->query("INSERT INTO ".TBL_NEWS."
  15.                                 (titre, intro, contenu, date, auteur_id, cat_id)
  16.                                 VALUE ($titre, $intro, $contenu, $date, $auteur_id, $cat_id)" );
  17.     }
  18.     
  19.     function delete($id_news) {
  20.         return $mysqli->query("DELETE FROM ".TBL_NEWS." WHERE id = ".$_GET['id']);
  21.     }
  22. }
  23. ?>


 

Code :
  1. <?php
  2. class newsView {
  3.     
  4.     function add() {
  5.         echo '<form action="'.$_SERVER['PHP_SELF'].'" method="post">';
  6.  
  7.         echo '<p><label>Nom de la news :</label><br />';
  8.         echo '<input type="text" name="titre" size="50" /></p>';
  9.         
  10.         echo '<p><label>Catégorie de la news :</label><br />';
  11.         echo '<select name="cat_id">';
  12.             echo '<option value="">&nbsp;</option>';
  13.         echo '</select></p>';    
  14.  
  15.         echo '<p><label>Introduction :</label><br />';
  16.         echo '<em>(peut-être laissé vide)</em><br />';
  17.         echo fckeditor('intro', '', 'Basic', '200px', '800px').'</p>';
  18.         
  19.         echo '<p><label>Texte principal :</label><br />';
  20.         echo fckeditor('contenu', '', 'Perso', '500px', '800px').'</p>';
  21.  
  22.         echo '<p><input type="submit" value="Ajouter la news" /></p>';
  23.         echo '</form>';
  24.     }
  25.     
  26. }
  27. ?>


 
Mon plus gros soucis actuellement : comment faire communiquer les différentes couches du MVC entre elles ?
Pour ma vue par exemple, lorsque l'utilisateur valide le formulaire, c'est sensé arriver sur le contrôleur. Comment dois-je procéder ?


---------------
Twitter
Reply

Marsh Posté le 30-06-2008 à 14:20:06    

Je comprend pas certains trucs :
- Pourquoi newsController au vue de ses attribut ne s'appelerait pas "news" tout simplement ?
- Pourquoi la class news (que je m'attend à etre une news) permet de gérer les news ? Je l'appelerais plutot newsModel ou newsManager.
- Pourquoi une classe pour la vue ? Wrapper du html dans une méthode d'une classe c'est tout sauf utile. Utilise un moteur de templates avec des templates comme Smarty par exemple. (idéal pour débuter car très documenté)
 
EDIT : pour répondre à tes questions :
il te faut un frontController qui reçoit toutes les requêtes, qui invoque un Routeur pour les parser puis qui appelle le bon controleur suivant la requête effectuée par réflexion. Exemple sur le net :
http://www.onlamp.com/pub/a/php/20 [...] oller.html

Message cité 1 fois
Message édité par vanadium le 30-06-2008 à 14:24:18
Reply

Marsh Posté le 30-06-2008 à 15:24:40    

vanadium a écrit :

Je comprend pas certains trucs :
- Pourquoi newsController au vue de ses attribut ne s'appelerait pas "news" tout simplement ?
- Pourquoi la class news (que je m'attend à etre une news) permet de gérer les news ? Je l'appelerais plutot newsModel ou newsManager.
- Pourquoi une classe pour la vue ? Wrapper du html dans une méthode d'une classe c'est tout sauf utile. Utilise un moteur de templates avec des templates comme Smarty par exemple. (idéal pour débuter car très documenté)
 
EDIT : pour répondre à tes questions :
il te faut un frontController qui reçoit toutes les requêtes, qui invoque un Routeur pour les parser puis qui appelle le bon controleur suivant la requête effectuée par réflexion. Exemple sur le net :
http://www.onlamp.com/pub/a/php/20 [...] oller.html


 
Le NewsController peut (à mon avis, suffi de regarder une structure MVC natif comme Rails) garder ce nom, idem pour News (le modèle). Pour la view, moi j'en ferai un dossier News, contenant un fichier .php par action, comme ça t'évites d'arriver avec un fichier NewsView de 15'000 lignes de xHTML.$
 
Par contre, dans NewsController, moi je remplacerait news_id par id ... On parle de news, c'est normal que si on dit "id" , c'est l'id d'une news.
Sinon moi j'utiliserais les requètes préparées au lieu de ton système de concaténation. C'est beaucoup plus safe contre les SQL Injections et de plus ça rendrait ton code plus lisible :o


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 30-06-2008 à 17:20:59    

vanadium => j'ai suivis les conseils donnés précédemment dans ce topic par rapport au MVC.
Pour un système de template, j'y pense, mais je n'y connais encore rien, donc ça me ferait une nouvelle (grosse ?) somme de connaissances à acquérir. Mais voulant faire quelque chose de bien, autant y aller jusqu'au bout.
 
Je prends ta remarque en compte pour le news_id qui devient id esox_ch.
Pour ce qui est des requêtes préparées, j'en ai toujours entendu parler, mais jamais vu à quoi ça ressemblait, je vais essayer de me documenter.


---------------
Twitter
Reply

Marsh Posté le 30-06-2008 à 20:23:06    

Reply

Marsh Posté le 06-07-2008 à 20:54:40    

Pour faire communiquer les différentes couches entre elles, par exemple pour mes news, c'est pas plus simple de faire une classe, qui serait une extension des trois couches ?


---------------
Twitter
Reply

Marsh Posté le 06-07-2008 à 21:16:36    

c'est le controelur qui est la pour faire communiquer le modele et la vue


---------------

Reply

Marsh Posté le 06-07-2008 à 21:30:50    

Donc le controlleur contient des fonctions de communication ?


---------------
Twitter
Reply

Marsh Posté le 06-07-2008 à 21:55:11    

Je dois utiliser un front controlleur pour faire communiquer mes différentes couches entre elles ?
 
Parce que j'y comprends rien après lecteur de l'article :/


---------------
Twitter
Reply

Marsh Posté le 06-07-2008 à 22:09:49    

koskoz a écrit :

Donc le controlleur contient des fonctions de communication ?


 
oui , le controleur instancie le modèle avec les bons paramètres et  appelle la bonne vue avec ce modele  

koskoz a écrit :

Je dois utiliser un front controlleur pour faire communiquer mes différentes couches entre elles ?
 
Parce que j'y comprends rien après lecteur de l'article :/


 
exemple , dans mon cas :  
 
un front controleur, qui est instancie le bon module  
certains modules ( gestion de document, agenda ) appelent d'autre contrôleur ( page dans la gestion de document , rendez vous dans une agenda) , qui peuvent eux meme continuer à descendre ( un champ d'une page )


---------------

Reply

Marsh Posté le 06-07-2008 à 22:45:50    

Ok, donc je dois comprendre le code dans la page que j'ai linké pour continuer d'avancer.
Bon, c'est pas gagné :/


---------------
Twitter
Reply

Marsh Posté le 07-07-2008 à 12:00:26    

Faut bien qu'il y ait un objet dont le rôle est de déterminer quel controleur / méthode il faut executer : ça s'appelle généralement un FrontControleur. :D
Souvent celui-ci délègue le parsing de l'url à un Routeur pour extraire de l'url le controleur et l'action à executer.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed