hametsu | Bonjour,
je soumet à votre critique ma réflexion sur le rôle des classes model et modeldao. L'une permet de définir, filtrer et valider des données, tandis que l'autre permet leur ajout/modification/supression et séléction dans la couche d'accès aux données.
Le code est assez commenté pour illustrer ma pensée :
Code :
- <?php
- // Classe de base pour tous les modèles.
- // Procure les méthodes de définiton/récupération des propriétés.
- // Permet de filtrer les données en amont et en aval.
- // Permet de valider les données pour leur enregistrement/modification.
- // Indépendant de la source des données.
- abstract class Model
- {
- // Contient la liste des erreures.
- protected $errors = array();
- // Constructeur.
- public function __construct($data)
- {
- foreach ($data as $name => $value)
- {
- $this->{$name} = $value;
- }
- }
-
- // Définie une propriété.
- public function __set($name, $value)
- {
- $this->{'set_'.$name}($value);
- }
-
- // Récupère une propriété.
- public function __get($name)
- {
- return $this->{'get_'.$name}();
- }
-
- // Vérifie qu'une propriété existe.
- public function __isset($name)
- {
- return (isset($this->{$name}));
- }
-
- // Supprime une propriété.
- public function __unset($name)
- {
- unset($this->{$name});
- }
-
- // Définie une erreure
- // $name : nom de la propriété
- // $message : message d'erreur
- public function set_error($name, $message)
- {
- $this->errors[$name] = $message;
- }
-
- // Récupère une erreure spécifique
- // $name : nom de la propriété
- public function get_error($name)
- {
- return (isset($this->errors[$name]) ? $this->errors[$name] : NULL);
- }
-
- // Récupère toutes les erreures
- public function get_errors()
- {
- return (!empty($this->errors) ? $this->errors : NULL);
- }
-
- // Méthode abstraite de validation des données
- abstract protected function is_valid();
- }
- // Classe de modèle d'article.
- class Model_Article extends Model
- {
- // Identifiant.
- private $id;
- // Titre.
- private $title;
- // Contenu.
- private $content;
-
- // Définie l'identifiant.
- public function set_id($id)
- {
- // Sécurise l'identifiant.
- $this->id = filter_var($id, FILTER_SANITIZE_NUMBER_INT);
- }
-
- // Récupère l'identifiant.
- public function get_id()
- {
- return (isset($this->id) ? $this->id : NULL);
- }
-
- // Définie le titre.
- public function set_title($title)
- {
- // Sécurise le titre.
- $this->title = filter_var($title, FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_ENCODE_HIGH);
- }
-
- // Récupère le titre.
- public function get_title()
- {
- return (isset($this->title) ? $this->title : NULL);
- }
-
- // Définie le contenu.
- public function set_content($content)
- {
- // Sécurise le contenue
- $this->content = filter_var($content, FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_ENCODE_HIGH);
- }
-
- // Récupère le contenu.
- public function get_content()
- {
- return (isset($this->content) ? $this->content : NULL);
- }
-
- // Valide les données
- public function is_valid()
- {
- // Pour le moment on ne va considérer que la validation des données
- // pour leur insertion.
- if (empty($this->title))
- {
- $this->set_error('title', 'Veuillez entrer un titre.');
- return FALSE;
- }
- if (empty($this->content))
- {
- $this->set_error('content', 'Veuillez entrer un contenu.');
- return FALSE;
- }
- return TRUE;
- }
- }
- // Classe de base du model d'accès aux données.
- abstract class Model_DAO
- {
- // Nom de la classe de modèle
- protected $model_class;
- // connexion avec la base de données.
- protected $dbh;
- // nom de la table.
- protected $table;
- // structure de la table.
- protected $schema;
-
- // Constructeur.
- // $dbh : connexion avec la base de données.
- public function __construct(PDO $dbh)
- {
- $this->dbh = $dbh;
- // Récupère le nom de la table
- // Model_DAO_<nom_dela_table>
- $this->table = substr(get_class($this), 10);
- $this->model_class = 'Model_'.$this->table;
- // La structure n'est pas définie ?
- // On peut imaginer plus tard la génération de structure,
- // puis leur inclusion plutôt qu'une requàªte...
- if (!isset($this->schema))
- {
- $sql = 'SHOW COLUMNS FROM '.$this->table;
- $stmt = $this->dbh->query($sql);
- // Le serveur de base de données ne réussit pas à executer de la requàªte ?
- if (!$stmt)
- {
- $error = $this->dbh->errorInfo();
- throw new Exception ($error[2]);
- }
- // Définie la structure de la table afin de pouvoir
- // travailler avec le modèle.
- $this->schema = $stmt->fetchAll(PDO::FETCH_ASSOC);
- }
- }
-
- // Insertion d'un nouvel enregistrement.
- // $model : instance de la classe modèle.
- public function insert(Model $model)
- {
- // Les données à insérées sont-elles valides ?
- if (!$model->is_valid())
- {
- return FALSE;
- }
- // Passe en revue la structure de la table.
- foreach($this->schema as $columns)
- {
- // Récupère le nom des colonnes.
- $names[] = $columns['Field'];
- // Récupérer les donnés contenues dans la classe modèle.
- // Appel <nom_du_modele>::get_<nom_de_la_colonne> ();
- $values[] = $model->{$columns['Field']};
- // Remplie un tableau de marqueurs pour la préparation de la
- // requàªte avant son execution.
- $binds[] = '?';
- }
- // Requàªte SQL
- $sql = 'INSERT INTO `'.$this->table.'` (`'
- . implode ('`, `', $names).'`) VALUES ('
- . implode(', ', $binds).')';
- // Prépare la requàªte SQL avec des marqueurs
- $stmt = $this->dbh->prepare($sql);
- // Le serveur de base de données ne réussit pas à préparer la requàªte SQL?
- if(!$stmt)
- {
- $error = $this->dbh->errorInfo();
- throw new Exception ($error[2]);
- }
- // Le serveur de base de données ne réussit pas à executer la requàªte SQL préparée ?
- if (!$stmt->execute($values))
- {
- $error = $stmt->errorInfo();
- throw new Exception ($error[2]);
- }
- // Déinie l'identifiant du dernier enregistrement inséré dans le modèle.
- $model->id = $this->dbh->lastInsertId();
- return TRUE;
- }
- // Met à jour un ou plusieurs enregistrement(s).
- // $model : instance de la classe modèle.
- public function update(Model $model)
- {
- // ...
- }
- // Supprime un ou plusieurs enregistrement(s).
- // $model : instance de la classe modèle.
- // On pourrait supprimer par l'identifiant ou
- // le nom d'une colonne si elle est définie.
- public function delete(Model $model)
- {
- // ...
- }
- // Sélectionne un ou plusieurs enregistrement(s).
- public function select()
- {
- // ...
- // On retourne une instance de la classe modèle
- // pour chaque enregistrement.
- $result = array();
- foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $record)
- {
- $result = new $this->model_class($record);
- }
- return $result;
- }
-
- // + implantation de méthode gérant les relations
- // one-to-one, one-to-many et many-to-many
- }
- // Classe de modèle d'accés au données des articles.
- class Model_DAO_Article extends Model_DAO
- {
- // Constructeur.
- // Surcharge de la classe parente.
- public function __construct($dbh)
- {
- $this->table = 'article';
- $this->model_class = 'Model_Article';
- parent::__construct($dbh);
- }
- }
- // Instance de la classe de base de données
- $dbh = new PDO('mysql:host=localhost;dbname=tournoi', 'root', 'root');
- // Ajout des données au modèle article
- $article = new Model_Article (array('id' => NULL, 'title' => 'Article\'s title', 'content' => 'This is the article content'));
- // Ajout de l'instance de la classe de base de données au modèle d'accès aux données.
- $article_dao = new Model_DAO_Article ($dbh);
- // Ajout de l'instance du modèle article pour insérer les données.
- if ($article_dao->insert($article))
- {
- echo '<p>Article ajouté avec succès.</p>';
- }
- else
- {
- // Récupération des erreures
- $errors = $article->get_errors();
- // 1er choix d'affichage
- // Ou bien une liste :
- echo '<ul>';
- foreach ($errors as $error)
- {
- echo '<li>'.$error.'</li>';
- }
- echo '</ul>';
-
- // 2ème choix d'affichage
- // A l'endroit ou se situe le champs titre du formulaire
- /*if (!empty($errors['title']))
- {
- echo '<p>'.$errors['title'].'</p>';
- }
- // A l'endroit ou se situe la zone de texte content du formulaire
- if (!empty($errors['content']))
- {
- echo '<p>'.$errors['content'].'</p>';*/
- }
- }
- // Pas implémenter dans l'exemple.
- // Uniquement à titre informatif...
- /*
- foreach ($article_dao->select() as $article)
- {
- echo '<p>id : '.$article->id.'</p><p>titre : '.$article->title.'</p><p>contenu : '.$article->content.'</p>';
-
- }
- */
- ?>
|
Message édité par hametsu le 05-12-2007 à 14:38:53
|