Organisation de mon code

Petit nouveau ! | 1 Messages

05 avr. 2015, 18:55

Hello à tous ;)
Je viens de commencer l'objet, et j'ai créé un mini système de news tout bête, et je voudrai avoir votre avis :

index.php

Code : Tout sélectionner

<?php $db = new PDO('mysql:host=localhost;dbname=db_name;charset=utf8', 'root', ''); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); function autoload($class) { require $class . '.php'; } spl_autoload_register('autoload'); $manager = new NewsManager($db); $liste = $manager->getList(); if ($_POST) { if (!empty($_POST['titre']) && !empty($_POST['contenu']) && !empty($_POST['auteur'])) { $titre = htmlspecialchars($_POST['titre']); $contenu = htmlspecialchars($_POST['contenu']); $auteur = htmlspecialchars($_POST['auteur']); $news = new News([ 'titre' => $titre, 'contenu' => $contenu, 'auteur' => $auteur ]); if (!$news->titreValide()) { $message = 'Le titre de l\'article doit être une chaine de caractères de maximum 255 caractères'; unset($news); } elseif (!$news->contenuValide()) { $message = 'Le contenu de l\'article doit être une chaine de caractères'; unset($news); } elseif (!$news->auteurValide()) { $message = 'L\'auteur de l\'article doit être une chaine de caractères de maximum 50 caractères'; unset($news); } else { $manager->addNews($news); $message = 'News ajoutée avec succès'; } } else { $message = 'Veuillez complèter tout les champs'; } } ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Les news</title> <link rel="stylesheet" type="text/css" href="style.css"/> </head> <body> <h1>Toutes vos news</h1> <div class="liste"> <?php foreach ($liste as $news) { echo '<div class="news">'; echo '<b>' . $news->auteur() . '</b> a écrit : <i>"' . $news->titre() . '"</i><br/>'; echo '<p>' . $news->contenu() . '</p>'; echo '</div>'; } ?> </div> <div class="message"> <?php if (!empty($message)) { echo $message; } ?> </div> <form method="post" action="" class="form_news"> <fieldset> <legend>Ajouter une news</legend> <div class="form_element"> <input type="text" name="titre" maxlength="255" placeholder="titre"/> </div> <div class="form_element"> <textarea name="contenu" placeholder="contenu"></textarea> </div> <div class="form_element"> <input type="text" name="auteur" maxlength="50" placeholder="auteur"/> </div> <div class="form_element"> <input type="submit" value="Ajouter"/> </div> </fieldset> </form> </body> </html>
News.php

Code : Tout sélectionner

<?php class News { private $_id, $_titre, $_contenu, $_auteur; public function __construct(array $data) { $this->hydrate($data); } public function hydrate(array $data) { foreach ($data as $key => $value) { $method = 'set' . ucfirst($key); if (method_exists($this, $method)) { $this->$method($value); } } } // GETTERS public function id() { return $this->_id; } public function titre() { return $this->_titre; } public function contenu() { return $this->_contenu; } public function auteur() { return $this->_auteur; } // SETTERS public function setid($id) { $id = (int)$id; if (is_int($id) && $id > 0) { $this->_id = $id; } else { trigger_error('ID DOIT ETRE DE TYPE INT ET SUPERIEUR A 0', E_USER_ERROR); return false; } } public function setTitre($titre) { if (is_string($titre)) { $this->_titre = $titre; } else { trigger_error('TITRE DOIT ETRE DE TYPE STRING', E_USER_ERROR); return false; } } public function setContenu($contenu) { if (is_string($contenu)) { $this->_contenu = $contenu; } else { trigger_error('CONTENU DOIT ETRE DE TYPE STRING', E_USER_ERROR); return false; } } public function setAuteur($auteur) { if (is_string($auteur)) { $this->_auteur = $auteur; } else { trigger_error('AUTEUR DOIT ETRE DE TYPE STRING', E_USER_ERROR); return false; } } public function titreValide() { if (!empty($this->titre()) && is_string($this->titre()) && strlen($this->titre()) < 256) { return true; } else { return false; } } public function contenuValide() { if (!empty($this->contenu()) && is_string($this->contenu())) { return true; } else { return false; } } public function auteurValide() { if (!empty($this->auteur()) && is_string($this->auteur()) && strlen($this->auteur()) < 51) { return true; } else { return false; } } }
NewsManager.php

Code : Tout sélectionner

<?php class NewsManager { private $_db; public function __construct($db) { $this->setDb($db); } public function setDb(PDO $db) { $this->_db = $db; } public function addNews(News $news) { $q = $this->_db->prepare('INSERT INTO news(titre, contenu, auteur) VALUES (:titre, :contenu, :auteur)'); $q->bindValue(':titre', $news->titre(), PDO::PARAM_STR); $q->bindValue(':contenu', $news->contenu(), PDO::PARAM_STR); $q->bindValue(':auteur', $news->auteur(), PDO::PARAM_STR); $q->execute(); $news->hydrate([ 'id' => $this->_db->lastInsertId() ]); } public function getList() { $q = $this->_db->query('SELECT * FROM news ORDER BY id DESC LIMIT 0,50'); $q->execute(); $liste = array(); while ($data = $q->fetch(PDO::FETCH_ASSOC)) { $liste[] = new News($data); } return $liste; } }
J'ai notamment une question qui me "turlupine" x).
Pour contrôler l'intégrité des données d'une news, j'utilise des méthodes du type "titreValide", néamoins, j'ai déjà mes setters qui vérifient (en partie), l'intégrité des données. La question, ces méthodes sont-elles appropriées ou y a t-il une meilleur manière de contrôler les données, comme par exemple directement contrôler les données dans le contrôleur sans utiliser des méthodes..

Merci d'avance ;)

ViPHP
ViPHP | 928 Messages

10 avr. 2015, 14:19

Normalement ton entité (News) ne devrait pas avoir à se soucier de valider ses données. Mieux vaut les valider dans ton controlleur.

Eléphanteau du PHP | 10 Messages

12 avr. 2015, 23:57

Tu devrais avoir un NewsManager.class.php qui vérifiera l'intégrité des données.

Dans l'idée, le mieux c'est :

Contrôlleur qui appelle des fonctions qui lui sont propres en fonction de ce qu'il se passe sur le site (exemple : est-ce que l'utilisateur est connecté ? si oui > controlleur::handleConnected(), si non controlleur::handleHome()) ; ces fonctions créeront des objets et appelleront leur manager pour vérifier l'intégrité des variables qui leur sont associées.

Détache donc tout le traitement en haut d'index.php dans une classe controlleur.

Ces objets viennent donc de simples models composés de variables, de getters et de setters. Aucune méthode (fonction) ici donc.
Les managers sont attachés à une classe chacun, et sont composés des méthodes dont on aura besoin sur les objets. En passant, les managers sont censés être composés de méthodes statiques, puisqu'ils ne servent à rien en tant qu'objet.

Pour finir, dans tes vues, évite : "if (!empty($message)) {
echo $message;
}", tu ne devrais qu'à avoir faire un simple echo. Le traitement des données doit être fait bien avant.

Pour résumé : Controlleur récupère les infos (models) traitées auparavant (managers) et les envoient aux vues en les chargeant par la même occasion, c'est lui qui dispatch les bonnes infos au bon endroit en fonction de l'activité qu'il y a sur le site.

Dans l'idée, l'index.php devrait ressembler à :
<?php

require_once 'src/controller/Controller.class.php';
use src\controller\Controller;

Controller::exec();
C'est très simpliste, mais c'est pour que tu comprennes l'idée.