Un exemle pratique mes requêtes dans mon modeles MVC

Rechercher

Un exemle pratique mes requêtes dans mon modeles MVC

Par dancom5  -  48 reponses  -  Le 27/01/2014 18:19  -  Editer  - 

Bonjour.

Me corriger si j'ai pas bien fait SVP.

J'ai un peu de difficulté à bien cerner ma séparation de structure mvc
du côté de mes requêtes SQL.

J'ai mis "abstract class Model extends pdo_mysql" dans le fichier modeles
et l'extentiation dans la partie vue. Bon.. c'est bien ou mal?

Aussi, je me demande si je pourrais plus rendre portable ma fonction :
public function getAll() ci-bas. Là, je veux afficher tout mais je vais
ajouter avec des critères au besoin.

Je suis obligé de créer une 2e fonction qui se répète avec une critère
en plus?

J'ai mis mes codes pour faire mon MVC:
dans \models\home.php

    <?php

    class HomeModel extends BaseModel
    {
            //data passed to the home index view
            public function index()
            {   
                    $this->viewModel->set("pageTitle","Accueil");
                    return $this->viewModel;
            }
    }

    abstract class Model extends pdo_mysql {
            private $_conn;
            protected $_pk;
            public function __construct() {
                    $this->_conn = pdo_mysql::pdo_connection();
            }

            // afficher tout
            public function getAll() {
                    try{
                        $stmt = $this->_conn->prepare("SELECT * 
                                                                                        FROM {$this->table}
                                                                                        ");
                        $stmt->execute();
                        return $stmt->fetchAll(PDO::FETCH_OBJ);

                    } catch (PDOException $est) {
                            die("pdo connection error! ". $est->getMessage() ."<br/>");
                    }
            }
    }

    // la table des artistes
    class Artistes extends Model {
            protected $table='artistes';

            public function __construct()
            {
                    parent::__construct();
                    //$this->_pk = 'id';
            }
    }

    ?>

dans \views\home.php

    <h1>Liste des Artistes!</h1>

    <?php 
    $artistes = new Artistes();
    $artistes = $artistes->getAll();

    foreach ($artistes as $a) {
    echo $a->id .' ';    
    echo $a->nom .' ';    
    echo $a->prenom .'<br>';    
    }
    ?>

Je souhaiterais une aide me donnant des indications du côté pratique.
Ça serait apprécié.

 

Réponses apportées à cette discussion

Par Cyrano  -  Le 27/01/2014 23:41  -  Haut de page  - 

Salut,
il semble au départ y avoir une erreur d'interprétation dans le fonctionnement d'une structure en MVC : tu décris une forme de lien entre modèle et vue. Or c'est justement ce que la structure en MVC s'efforce d'éviter : c'est le contrôleur qui établit d'une certaine manière ce lien : le contrôleur reçoit la requête HTTP, il sélectionne alors selon les paramètres le modèle approprié pour collecter les données et les traiter si besoin est. Ensuite, il sélectionne la vue appropriée et l'alimente avec les données récupérées du modèle et construit la page à retourner vers l'utilisateur. Le modèle n'a absolument aucun lien direct avec la vue et vice-versa.

Quant à ton code, tu pourrais avantageusement simplifier, par exemple comme ceci :

    <?php  
    class HomeModel extends BaseModel  
    {  
        //data passed to the home index view  
        public function index()  
        {  
            $this->viewModel->set("pageTitle", "Accueil");  
            return $this->viewModel;  
        }  
    }  

    class Model extends pdo_mysql  
    {  
        private $_conn;  
        protected $_pk;  
        protected $_table;  
        public function __construct($nomTable)  
        {  
            $this->_conn = pdo_mysql::pdo_connection();  
            $this->_table = $nomTable;  
        }  

        // afficher tout  
        public function getAll()  
        {  
            try  
            {  
                $stmt = $this->_conn->prepare("SELECT * FROM {$this->_table}");  
                $stmt->execute();  
                return $stmt->fetchAll(PDO::FETCH_OBJ);  
            }  
            catch(PDOException $est)  
            {  
                die("pdo connection error! " . $est->getMessage() . "<br/>");  
            }  
        }  
    }  

Et ensuite, ton code métier :

    <h1>Liste des Artistes!</h1>  

    <?php  
    $oArtistes = new Model('artistes');  

    $aArtistes = $oArtistes->getAll();  

    foreach($aArtistes as $a)  
    {  
        echo $a->id . ' ';  
        echo $a->nom . ' ';  
        echo $a->prenom . '<br>';  
    }  
    ?>  

Observe bien `ta classe abstraite ne l'est plus (abstraite : compte tenu du peu de code contenu dans ton modèle original, ça ne présente aucun intérêt. Donc on remet ta classe Model publique et le constructeur reçoit en paramètre le nom de la table appropriée.

Ensuite, dans ton code métier, attention aux nomsde tes variables : tu crées une bizarrerie en utilisant le même nom pour l'objet et le tableau derésultat, c'est le meilleur moyen de t'emmêler les pinceaux. DOnc on nomme les variables avec un préfixe en fonction du type, un « o » si c'est un Objet, un « a » si c'est un tableau (Array)

Essaye ça, ça devrait aussi bien fonctionner. Si ça ne répond pas à tes questionnements, reviens en montrant le code de ton contrôleur ;)

 
Par dancom5  -  Le 28/01/2014 14:29  -  Haut de page  - 

Merci :-)

Je pensais qu'il fallait séparer la "class Model extends pdo_mysql" vu qu'il y a l'appel à la base de donnée via le constructeur de la partie requête via "public function getAll()".

La couche METIER serait l'extentiation mais ça irait dans la partie "Model" et non dans la "Vue".

D'après toutes mes lectures, la couche MODEL contiendrait deux parties:

  • la logique liée à la base de donnée
  • Les manipulations de la base de donnée

Quand mettre dans controleur et quand mettre dans couche Métier, et dans quelle partie de métier?

Les sites parlent de théories mais très peu d'exemples.

Le site sur lequel je regarde en ce moment, c'est celui-là:
http://notes.mazenod.fr/tp-architecture-mvc.html
Mais, c'est du procédural

 
Par Cyrano  -  Le 28/01/2014 15:12  -  Haut de page  - 

Ok, tes questionnement sont logiques.

Ce qui m'a amené à simplifier de la sorte, c'est que ton modèle ne contenait rien et n'était qu'une étape intermédiaire sans grand intérêt. Maintenant, il y a peut-être lieu de te poser la question suivante : comment séparer le code métier des librairies. Et du coup, qu'est-ce qui, dans ton code, mériterait peut-être d'être migré vers une librairie de ce qui devrait rester dans le code métier ?

Autre point relativement important : une classe ne doit faire qu'une chose et la faire bien. Alors revenons vers ton code de départ avant mes suggestions de modification. Dans ta classe abstraite, il y a plusieurs choses : la connexion, et l'exécution de requêtes. Ça en fait une de trop, ce qui veut dire que ta connexion devrait faire l'objet d'une classe spécifique dont l'instance serait passée à l'autre si besoin est. Ensuite, celle qui exécute les requêtes SQL ne les devrait pas les définir, elle devrait les recevoir en paramètre, les exécuter et retourner le résultat : du coup, les requêtes SQL devront être définies ailleurs. Où ? Dans tes modèles.

Et là, je m'arrête le temps que tu digères un peu tout ceci : qu'est-ce que ça t'inspire ?

 
Par dancom5  -  Le 28/01/2014 15:22  -  Haut de page  - 

J'ai bien pensé que quelque chose n'allait pas. Je crois qu'il serait approprié de repartir à zéro à partir d'un code procédural qui ne fait qu'un "listing" et de le décomposer pour en faire un MVC.

Et, de faire en sorte que ce soit PDO et l'orienté objet qui en ressort.

OK.. je vais faire un simple listing et en suite, je converti pour en faire un MVC. Je vais revenir la dessus.

Je fais cela durant la journée. Bon, c'est reparti :-)

 
Par Cyrano  -  Le 28/01/2014 15:30  -  Haut de page  - 

L'approche me parait bien compliquée.

Si tu pars d'un système en procédural, tâche plutôt d'identifier ce qui peut être converti en objets réutilisables, construis les classes et migre ça dans des librairies. Normalement, il ne devrait rester que ton code métier et à partir de là, il sera à mon sens beaucoup plus facile de séparer ce dernier en différentes couches : le contrôleur, les modèles et les vues.

Tu es en train d'éprouver les difficultés de la conception d'une architecture logicielle : c'est toujours un moment compliqué parce qu'il est assez peu évident de savoir ce qui pourrait ou non devenir un objet indépendant du reste qu'on instancie pour en utiliser les propriétés et les méthodes.

Ha si, autre détail oublié tout à l'heure : on parle « d'extension » et pas « d'extentiation » qui n'existe pas du tout, même en anglais ;)

 
Par dancom5  -  Le 28/01/2014 15:33  -  Haut de page  - 

Qu'entendez-vous par librairies?

Tout ce qui ne vas pas dans la vue, le model et le controleur?

Genre, les javascripts, images.

 
Par Cyrano  -  Le 28/01/2014 15:47  -  Haut de page  - 

Ha... j'ai peut-être bien fait d'évoquer la question finalement.

On pourrait effectivement presque dire que c'est comme les JavaScripts et les images, mais presque seulement. Les librairies, ce sont des classes, le plus souvent regroupées par packages qui sont complètement indépendantes d'une quelconque application.
Si on comparait avec le JavaScript, je prendrais l'exemple suivant : supposons que tu utilises Jquery. Tu ne modifies jamais Jquery, éventuellement tu ajouteras des plugins ou tu les écriras toi-même, mais même sans plugin, le seul code JavaScript que tu écris va s'appuyer dessus : Hé ben le code que tu écris, c'est le code métier, Jquery.js, c'est ta librairie. Le code que tu écris ne sert qu'à ton application et n'est en général pas portable du tout dans la mesure où il a été écrit spécifiquement. Jquery en revanche peut être utilisé dans n'importe quelle application.

En PHP, c'est sensiblement pareil : tu écris une application ou un site web spécifique. Pour ce faire, tu vas élaborer du code spécialement conçu pour ça, mais au lieu de devoir tout écrire, tu peux appuyer ton code sur des librairies existantes, par exemple des classes issues du Zend Framework ou de Synfony ou de Hoa ou que tu auras écrites toi-même, classes qui servent à un type de traitement particulier quelle que soit l'application dans laquelle tu l'utilises. La classe possède des propriétés et des méthodes et sert à un type spécifique de traitement, rien de plus, rien de moins. Par exemple, tu veux pouvoir produire des fichiers PDF, au lieu de te taper d'écrire tout le code relativement complexe nécessaire à ça, tu vas importer dans un répertoire de librairies de ton application le package Zend_Pdf et ses dépendances du Zend-Framework.

Ici, pour reprendre ton exemple, il y a un élément assez générique qu'on retrouve dans quasiment tous les sites web de n'importe quelle catégorie : l'accès aux données : se connecter à un serveur de base de données, exécuter des requêtes SQL données, en récupérer le résultat et le retourner : c'est typiquement du code que tu ne devrais pas avoir besoin de ré-écrire à chaque nouvelle création de site.

Est-ce que c'est plus clair de cette façon ?

 
Par dancom5  -  Le 28/01/2014 16:04  -  Haut de page  - 

Oui, on mets dans les librairies les codes qui peuvent servir ailleur sans être obligé de les modifier.

Je regardais comme exemple, ce site-ci:
http://blog.nalis.fr/index.php?post/2009/10/19/Architecture-%3A-Le-Design-Pattern-MVC-en-PHP

c'est pour cela que je disais me baser sur le procédural. C'est que cet exemple, n'est pas en objet.

Je vais faire comme vous me le proposez.

 
Par Cyrano  -  Le 28/01/2014 16:12  -  Haut de page  - 

J'imagine qu'à travers divers tutos tu as pu voir des schémas, des croquis montrant des classes avec des interactions sous forme de liens, des flèches entre les différentes classes, et pour chaque classe, leur nom, quelques propriétés et quelques méthodes, et à travers tout ça des notions d'UML.

Essaye de reproduire un schéma de ce type pour « dessiner » ton application, ce sera plus clair même pour toi. Partant de là, tu auras déjà fait pratiquement la moitié du travail de développement ;)

N'oublies pas non plus que le MVC, c'est un Design Pattern composite, ce qui veut dire que pour mettre ça en place, il serait souhaitable d'avoir de bonnes notions de base des design patterns, et donc de programmation orientée objet. Là, on dirait que tu essayes de tout assimiler d'un seul coup. Tu t'attelles à un travail d'apprentissage assez conséquent que je n'aurais personnellement pas du tout tendance à recommander. Mais bon, si tu es à l'aise avec ça, alors continues, ça devrait bien aller :)

 
Par dancom5  -  Le 28/01/2014 16:23  -  Haut de page  - 

Je suis tombé sur ce site qui je pense peut m'aider à distinguer les éléments mvc

http://bpesquet.developpez.com/tutoriels/php/evoluer-architecture-mvc/

 
Par Cyrano  -  Le 28/01/2014 16:37  -  Haut de page  - 

Ok, ça a l'air effectivement assez complet mais là, je n'ai pas le temps de le lire dans son intégralité, j'essayerai de trouver du temps ce soir pour ça.

J'ai juste parcouru en diagonale et j'ai relevé quand même un truc : le code de départ que tu as posté ici part d'un moment du début du tuto... et la suite est pourtant au moins aussi importante. Au début, il montre des codes qui ne sont pas optimisés pour affiner petit à petit. L'idée, c'est expliquer à celui qui le lit en lui montrant des exemples avec lesquels il est familier parce que ça va ressembler beaucoup à son propre code. Il faut lire patiemment et comprendre en allant jusqu'au bout, et en revenant sur tel ou tel élément lorsqu'on bloque dessus.

Comprends bien que l'architecture en MVC, c'est pratiquement du « Full Objet », on est très très loin du procédural, et tout ce qui reste normalement en procédural à la fin de tout ça, c'est le code de la page index.php : tout le reste, c'est de la POO. Il faut donc maitriser un minimum les différentes notions de classes, de niveau d'accès (private, public, protected), d'abstraction, d'héritage, de polymorphisme et les design patterns avant d'aboutir à ça. Ça fait quand même un gros morceau à avaler, et la digestion risque d'être laborieuse ;)

 
Par dancom5  -  Le 29/01/2014 16:40  -  Haut de page  - 

J'ai téléchargé l'exemple MVC Orienté Objet que je vais étudier.

Mais, j'avoue que ce ne sera pas facile, puisque ça fait beaucoup plus de code que le procédural.

Celui que j'ai pris est ceci:
https://github.com/bpesquet/MonBlog/tree/mvc-objet

Pour essayer de le rendre le plus simple possible, je supprime la partie commentaire pour n'avoir que le stricte nécessaire et absolue afin de me faire une meilleure idée de la chose. Je pourrais aussi, en y pensant bien, prendre la version procédural pour comparer. Je viens d'y penser.

Merci pour les encouragement via tes réponses. J'apprécie beaucoup.

Je vais y revenir pour plus approfondir.

Ajout au message après:
J'ai pris la version mvc procédural et j'ai supprimé les codes sur les commentaires pour n'avoir qu'une base le plus simple possible. Pour afin réaliser le côté objet.

 
Par dancom5  -  Le 31/01/2014 07:26  -  Haut de page  - 

Salut Cyrano,

Je me demande à propos de cette syntaxe:

$billets = $this->billet->getBillets();

$this->billets c'est l'attribut qui va chercher, mais l'autre ->getBillets(), c'est la fonction si je ne me trompe pas.

Les trois ensemble?

 
Par Cyrano  -  Le 31/01/2014 07:32  -  Haut de page  - 

Pas tout à fait.

Ici, on a d'abord « $this » qui est un objet en soi. Ensuite, cet objet contient ce qu'on nomme une dépendance, disons en quelque sorte une propriété qui elle même est un objet, donc « billet ». Comme cette propriété est un objet, il comporte lui aussi des propriétés et des méthodes qui peuvent être appelées.

Donc en résumé, dans « $this », on appelle la méthode « getBillets() » de l'objet « billet » qui est une propriété-objet.

 
Par dancom5  -  Le 31/01/2014 07:48  -  Haut de page  - 

Je vais essayer de phraser ceci :

class ControleurAccueil {

private $billet;

public function __construct() {
    $this->billet = new Billet();
}

// Affiche la liste de tous les billets du blog
public function accueil() {
    $billets = $this->billet->getBillets();
    $vue = new Vue("Accueil");
    $vue->generer(array('billets' => $billets));
}

}

getBillets fait une requète SQL dans le Model,

Franchement, je ne sais pas comment phraser cela.

Je comprends en bonne partie chacun des éléments
mais l'ensemble..

 
Par Cyrano  -  Le 31/01/2014 10:35  -  Haut de page  - 

Si, regarde, ton code ré-ajusté avec un ajout, ce sera peut-être plus clair

<?php
class Billet
{
    public function getBillets()
    {
        //...
    }
}
class ControleurAccueil
{
    private $billet;
    public function __construct()
    {
        $this->billet = new Billet();
    }

    // Affiche la liste de tous les billets du blog
    public function accueil()
    {
        $billets = $this->billet->getBillets();
        $vue = new Vue("Accueil");
        $vue->generer(array('billets' => $billets));
    }
}

Comme tu peux voir, avec la classe billet, depuis ton contrôleur tu appelles la méthode de cette classe : le truc à assimiler, c'est que dans ton contrôleur, « $this-billet » est un objet avec ses propriétés et ses méthodes.

 
Par dancom5  -  Le 04/02/2014 01:41  -  Haut de page  - 

Peut-t-on faire un mixe de procédural et d'objet?

C'est que depuis le temps que je suis sur l'apprentissage de l'orienté objet, j'ai encore beaucoup de difficultés à me démêler à l'ensemble du code.

J'arrive bien à faire un bout de code pour faire un "listing" à partir de la base de données mais les relations entre les fichiers disons MVC pour faire un "listing" avec des bouts de code répartis sur plusieurs fichiers, j'ai encore beaucoup de misère à faire le lien entre les fichiers par rapport au code.

Avant, je codais en classique genre un fichier pour l'entête, un pour le pieds et un pour le corps (body) et un pour le menu. Mes requêtes était dans un seul bout de code. Là, j'ai appris à séparer le PHP du HTML en utilisant un contrôleur, le modèl et la vue simple. Mais j'y arrive en version procédural, en objet, je n'y arrive pas vraiment à part de faire des bouts de code comme faire une class pour faire un simple "listing".

En tout cas, c'est plutôt compliqué à gérer tout cela malgré mon désire d'apprendre ce type de programmation.

Je me demande s'il n y a pas un compromis entre le procédural et l'objet.

Merci beaucoup Cyrano pour toutes les effets que tu m'apportes.

Dan.

 
Par Cyrano  -  Le 04/02/2014 06:43  -  Haut de page  - 

Salut,
c'est effectivement toujours possible, et je dirais que c'est la magie de PHP, ça reste accessible par paliers à n'importe quel niveau. POO ne signifie pas obligatoirement MVC. On peut le faire mais rien n'y oblige.

Donc tu peux programmer l'essentiel en procédural : mais au fur et à mesure, pour certains traitements, tu trouveras sans doute pratique de disposer de classes et d'objets. Et à force de pratiquer l'objet, tu en arriveras à concevoir non seulement des classes mais des packages et tu arriveras assez naturellement et petit à petit aux Design Patterns... et donc à terme au MVC qui est, rappelons-le quand même, un Design Pattern composite ;)
Mais dans l'ensemble tu as raison sur la manière d'avancer : utilises ce avec quoi tu es à l'aise, donc le procédural pour l'instant, l'objectif reste que le résultat voulu soit obtenu avec efficacité, et l'utilisation de classes et d'objets s'insinuant au fil du temps et de ta compréhension de ces concepts parfois flous.

 
Par dancom5  -  Le 05/02/2014 20:16  -  Haut de page  - 

Je me rends compte que si je veux afficher avec et sans critères, je dois
mettre en objet. J'ai comme pas vraiment le choix. J'ai pris un exemple
objet de Nathan et j'ai réduit aux maximum le code afin de n'avoir que
l'essentiel pour la compréhention.

Je me rends compte que si je mets dans le fichier MODEL/Billet.php la
requête sur la table "articles", je dois avoir aussi VUE/vueAccueil.php
les bons champs pour l'affichage.

Mais, si je change, par exemple ma table "articles" pour afficher "artistes",
je dois changer l'affichage dans la vueAccueil.php. Mais, il peut arrivé que
je l'internaude décide d'afficher à la demande avec ou sans crtière. Ou bien
afficher avec et sans critères. Dois-je créer obligatoirement deux fois
dans MODEL/Billet.php ma requête? Aussi dans l'affichage?

CONTROLEUR/ControleurAccueil.php:

<?php

require_once 'Modele/Billet.php';
require_once 'Vue/Vue.php';

class ControleurAccueil {

        private $billet;

        public function __construct() {
                $this->billet = new Billet();
        }

// Affiche la liste de tous les billets du blog
        public function accueil() {
                $billets = $this->billet->getBillets();
                $vue = new Vue("Accueil");
                $vue->generer(array('billets' => $billets));
        }

}

CONTROLEUR/Routeur.php:

<?php

require_once 'Controleur/ControleurAccueil.php';
require_once 'Vue/Vue.php';
class Routeur {

        private $ctrlAccueil;
        private $ctrlBillet;

        public function __construct() {
                $this->ctrlAccueil = new ControleurAccueil();
        }

        public function routerRequete() {
                                $this->ctrlAccueil->accueil();
        }

}

MODEL/Model.php:

<?php

abstract class Model {

        private $bdd;

        protected function executerRequete($sql, $params = null) {
                $resultat = $this->getBdd()->prepare($sql);  // requête préparée
                $resultat->execute($params);
                return $resultat;
        }

        private function getBdd() {
                if ($this->bdd == null) {
                        $this->bdd = new PDO('mysql:host=localhost;dbname=ptg;charset=utf8',
                                        'root', '',
                                        array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
                }
                return $this->bdd;
        }

}

MODEL/Billet.php:

<?php

require_once 'Modele/Model.php';

class Billet extends Model {

        public function getBillets() {
                $sql = 'SELECT * FROM articles';
                $billets = $this->executerRequete($sql);
                return $billets;
        }

}

VUE/gabarit.php:

<!doctype html>
<html lang="fr">
        <head>
                <meta charset="UTF-8" />
                <link rel="stylesheet" href="Contenu/style.css" />
                <title><?= $titre ?></title>
        </head>
        <body>
                <div id="global">
                        <header>
                                <h1 id="titreBlog">Mon Blog</h1>
                                <p>Je vous souhaite la bienvenue sur ce modeste blog.</p>
                        </header>
                        <div id="contenu">
                                <?= $contenu ?>
                        </div> <!-- #contenu -->
                        <footer id="piedBlog">
                                Blog réalisé avec PHP, HTML5 et CSS.
                        </footer>
                </div> <!-- #global -->
        </body>
</html>

VUE/Vue.php:

<?php

class Vue {

        private $fichier;
        private $titre;

        public function __construct($action) {
                $this->fichier = "Vue/vue" . $action . ".php";
        }

        public function generer($donnees) {
                $contenu = $this->genererFichier($this->fichier, $donnees);
                $vue = $this->genererFichier('Vue/gabarit.php',
                                array('titre' => $this->titre, 'contenu' => $contenu));
                echo $vue;
        }

        private function genererFichier($fichier, $donnees) {
                if (file_exists($fichier)) {
                        extract($donnees);
                        ob_start();
                        require $fichier;
                        return ob_get_clean();
                }
                else {
                        throw new Exception("Fichier '$fichier' introuvable");
                }
        }

}

VUE/vueAccueil.php:

<?php $this->titre = "Mon Blog"; ?>

<?php foreach ($billets as $billet):
        ?>
        <article>
                <header>
                                <h1 class="titreBillet"><?= $billet['titre'] ?></h1>
                </header>
                <p><?= $billet['contenu'] ?></p>
        </article>
        <hr />
<?php endforeach; ?>

VUE/vueErreur.php:

<?php $this->titre = "Mon Blog - Erreur !"; ?>

<p><?= $msgErreur ?></p>
 
Par Cyrano  -  Le 05/02/2014 22:21  -  Haut de page  - 

Salut Dan,
je vais tâcher de rester compréhensible dans les explications qui suivent pour que ce soit clair, et ce n'est pas évident du tout.

Lorsque je me suis moi-même posé ces questions, il a fallu que je trouve une manière de faire pour que le résultat souhaité par l'internaute corresponde à son attente. Ceci étant, il faut garder à l'esprit que le choix de l'internaute reste limité aux actions qu'on met à sa disposition. Gardons ton exemple : une page qui affiche des articles. Sur cette page, on peut avoir ou non des paramètres, mais par défaut, lors de l'affichage initial, il n'y a pas de paramètres. Un peu comme la page d'accueil d'un blog où on peut voir une suite de titre des derniers articles publiés avec le début du texte de chaque article. Le titre de chaque article est cliquable et le lien pointe vers la même page mais comporte un paramètre supplémentaire : l'identifiant de l'article. Mais comme dans la page on a aussi la possibilité de sélectionner les auteurs des articles, mettons qu'on les nomme « artistes » pour que ça se rapproche au mieux de ton exemple, mettons que sous le titre de chaque article on ait un autre lien qui pointe vers la page de l'artiste. Déjà on a deux pages distinctes : soit les articles, soit les artistes.

Ça devient compliqué ? Peut-être pas tant que ça. Finalement, on a deux pages. Maintenant, ça ne me dit pas comment je vais organiser mon code. Je dirais tout simplement qu'il faut découper par « domaine » : ça veut dire quoi ? Ça signifie que tu as sur l'ensemble des liens de ton site différents domaines traités : ici, les articles et les artistes.
Maintenant, revenons au domaine des articles (les billets de ton exemple) : j'ai ou non un paramètre à prendre en compte. Mon contrôleur « articleControleur » doit permettre de distinguer ce détail pour collecter les données appropriées. Si je n'ai pas de paramètres, je vais par exemple récupérer tous les titres et les 5 premières lignes de chacun de ces articles. Si j'ai l'identifiant d'un article en paramètre, je vais récupérer seulement ces informations. En pratique, ça veut dire que le contrôleur devra appeler dans le modèle la méthode appropriée, par exemple, on appellera Billet->listeArticles(10) ou bien Billet->article(123) : la première méthode récupèrera les titres, les auteurs, une partie du texte et quelques informations des 10 derniers articles, alors que la seconde collectera les informations uniquement sur l'article identifié par la clé primaire « 123 ». Dans le même fichier billet.php, j'aurai deux méthodes, l'une pour collecter le nombre d'articles indiqué en paramètre, l'autre collectera les informations sur un article précis. Chacune de ces méthode comprendra une requête paramétrée ou non pour les données souhaitées.

Maintenant si je veux des informations sur les artistes, alors il me faudra créer un modèle « artiste » avec les méthodes appropriées : par exemple listeArtistes(), ficheArtiste($idArtiste), etc.. selon les besoin du contrôleur.

Partant de là, est-ce que tu te poses les bonnes questions. Dans tous les cas de figure, le conseil que je serais le plus enclin à donner est le suivant : Pars du résultat attendu : analyse ta page et détermines la liste des éléments dont tu as besoin pour construire ce résultat. Définis à partir de là les éléments que devra prendre en compte le contrôleur pour construire ce résultat : il y a ou non des paramètres, il s'agit de tel ou tel contrôleur, et la présence ou non de tel ou tel paramètre va définir l'action. Dans ta classe de contrôleur, tu devras alors définir des méthodes d'action pour chaque cas, le cas sans paramètre, le cas avec tel paramètre, le cas avec tel autre paramètre, etc... De là, tu devras faire appel à tel ou tel modèle qui lui collectera les données appropriées et les retournera : ce modèle pourra éventuellement comporter une ou plusieurs méthodes selon le cas et la méthode d'action du contrôleur devra définir laquelle appeler pour obtenir le résultat attendu. Par la suite, chaque méthode d'action du contrôleur va définir la (ou les différentes) vue(s) à mettre en oeuvre pour afficher les valeurs des données récupérées.

Je n'ai pas vraiment de code à te montrer pour illustrer tout ça, ça reste relativement abstrait, mais j'espère malgré tout que tu visualises mieux le fonctionnement de cette manière.

Dernier détail : tu dis ne pas avoir le choix de l'objet, je te garantis que tu as toujours ce choix, à ce détail près que dans certains cas, un développement en procédural sera plus lourd et beaucoup moins souple et encore moins pratique.

 
Par dancom5  -  Le 07/02/2014 09:36  -  Haut de page  - 

Comme, je suis très visuel, je comprends plus avec des exemples.

J'ai trouvé ce URL qui montre un exemples de MVC:
http://runnable.com/UoIuNLC5kKoeAAA4/how-to-create-professional-websites-in-php-mvc-design-pattern

Avec les exemples précédentes, je vais tenter de construire un code plus complet.

Vos dernières explications précédentes devraient m'aider.

Si j'arrive à faire en sorte pour y inclure la base de données. Ça va être déjà quelque chose.

 
Par Cyrano  -  Le 07/02/2014 09:48  -  Haut de page  - 

Le problème, c'est que même un bout de code n'est pas forcément utile visuellement.

Regarde ce document PDF, tu y trouveras des notions et surtout des images illustrant le fonctionnement d'une architecture en MVC.

 
Par dancom5  -  Le 07/02/2014 12:20  -  Haut de page  - 

Le lien ne fonctionne pas pour ce document.

Hé!! Merci pour tes interventions.

 
Par Cyrano  -  Le 07/02/2014 13:14  -  Haut de page  - 

Oups, désolé, j'ai édité le lien, il fonctionne à présent ;)

 
Par dancom5  -  Le 13/02/2014 04:24  -  Haut de page  - 

Bonjour Cyrano, du même auteur, j'ai trouvé à propos des bases de données:
http://www.jcc40.fr/wp-content/uploads/2012/03/bdd.pdf

Ça va m'aider pour réaliser mon projet.

Je m'attarde encore sur le lien que tu m'as donné.

Bonne journée!

 
Par Cyrano  -  Le 13/02/2014 07:32  -  Haut de page  - 

Salut,
j'ai jeté un coup d’œil, j'émets certaines réserves.

Si tu veux construire une base de données, voici une page qui sera beaucoup plus instructive et surtout avec des règles beaucoup plus justes.

 
Par dancom5  -  Le 13/02/2014 08:00  -  Haut de page  - 

Pour le MVC, j'ai supprimé ce qui touchait les aspects GD pour simplifier et j'ai tenter de rajouter une limite à 5 et je ne voyais pas comment j'aurais pu le faire en respectant l'orienté objet.

Bon. J'essaie de voir un truc plus simple mais ce n'est pas objet ni pdo:
http://www.wewereweb.be/comprendre-le-pattern-mvc-avec-un-exemple-simple/2012/03/15/

J'ai jamais eu autant de misère avec l'apprentissage en PHP.

Si j'arriverais à mettre en objet le dernier exemple tout en mettant en PDO.

Je vais aller voir pour le lien de la base de données.

 
Par Cyrano  -  Le 13/02/2014 08:12  -  Haut de page  - 

Pour l'accès aux données, essaye d'imaginer ceci : schématiquement, tu as une télécommande et lorsque tu as des manipulations de données à effectuer, tu utilises un des boutons qui va alors envoyer une requête appropriée.

Cet illustration devrait être plus facile à concevoir. Dès lors, si on fait le parallèle avec le PHP, tu crées une classe d'accès aux données qui sera la « télécommande » dont chaque bouton est une méthode. Il te faut donc faire la liste des méthodes dont tu as besoin pour interagir avec ta base de données, et pour chaque méthode de quels paramètres il faudra pouvoir disposer pour que ça fonctionne et à quel moment. Par exemple, lorsque tu veux utiliser ta télécommande, il faut qu'il y ait une pile dedans : pour ta classe, ça correspond à ton constructeur auquel tu vas passer en paramètre la « pile » sous la forme des paramètres de connexion.

Pars de ce que tu fais lorsque tu l'écris en procédural et tâche d'isoler chaque action pour établir ta liste de méthodes. Implémentes tout ça dans une classe Bdd, tu pourras alors disposer d'un objet.

Peut-être que ça fera une grosse classe, mais ensuite, tu pourras toujours découper ça en différentes classes liées dans un package, tu n'accèderas toujours qu'à ta classe Bdd, mais celle-ci s'appuiera si besoin est sur les autres classes du package.

 
Par dancom5  -  Le 14/02/2014 04:15  -  Haut de page  - 

A partir de cette base, je vais tenter de faire un MVC et un Objet:

<?php

$db = new PDO('mysql:host=localhost;dbname=ptg;charset=utf8', 'root', '');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

$stmt = $db->query('SELECT * FROM artistes');
$results = $stmt->fetchAll(PDO::FETCH_OBJ);

foreach($results as $r) {
        echo $r->id.' '.$r->nom.'</br>';
}

?>

dans un fichier index.php pour commencer et ensuite créer les séparations puis les objets en suivant vos conseils précédents. J'aurais surement besoin de vos indices pour m'améliorer.

 
Par Cyrano  -  Le 14/02/2014 06:43  -  Haut de page  - 

Mouais... il faut avancer étape par étape et être patient dans ce genre d'apprentissage.

Je sais que c'est parfois parfois pris comme un effet de mode de faire du MVC, le problème c'est que d'abord ça n'a rien d'une mode, ensuite il est primordial de comprendre ce qu'est le MVC : c'est un design pattern composite. Ça implique qu'on sait quand même un tout petit peu au départ ce que sont les design patterns.... et par aboutissement logique, qu'on connait relativement bien la programmation orientée objet. Je ne peux que regretter que certains tutos diffusés largement sur le web présentent les choses de manière un peu trop simplistes : c'est certain qu'ils sont convaincants lorsqu'ils exposent l'importance de découper les applications pour rendre ça plus souple et plus facile à maintenir, mais il manque le plus souvent de gros morceaux tout à fait essentiels à la mise en application de tout ça.

Vouloir assimiler tout ça en même temps m'apparait comme très ambitieux pour ne pas dire totalement irréalisable : c'est très exactement vouloir mettre la charrue avant les bœufs, quoique cette expression pour les citadins que nous sommes en majorités n'ait pas beaucoup de sens, je pourrais illustrer par un autre exemple peut-être plus parlant : c'est vouloir parcourir une certaine distance en voiture en oubliant totalement qu'il serait judicieux et même indispensable au départ de faire le plein.

Donc ma suggestion est la suivante : pars effectivement d'une construction de base simple, commence par découper certains codes en les déportant dans des classes aussi génériques et réutilisables que possible. Ensuite on pourra parler de design pattern et en toute fin on pourra aborder les principes du MVC, mais en toute fin seulement. Parce que le MVC, c'est une méthode de découpage de classes en packages selon des principes particuliers, principes qu'il convient de connaitre un minimum au départ pour chacun d'en eux.

 
Par dancom5  -  Le 15/02/2014 06:01  -  Haut de page  - 

Je crois que ce site peut peut-être m'aider à comprendre le procédé de conversion de "procédural" à "orienté objet" :
http://wiki.jeuweb.org/tutoprog/passage_a_la_poo

Un autre lien:
http://www.lepotlatch.org/2007/03/65-php-pourquoi-passer-au-developpement-oriente-objet-oo/

Disons une partie.

A partir de la requête de mon dernier message, faire des fonctions pour séparer le code et convertir cela en objet. Donc, je vois au moins deux class d'après-moi.

Une class singleton pour la connexion et une pour le listing résultant de la requête.

'SELECT * FROM artistes'

Ensuite, je sépare l'affichage HTML dans un fichier qui ne fera que cela. Comme, j'ai deux class, je devrai utiliser deux fichier qui irai dans le fichier model, puisque la class de connexion c'est de la logique ou du traitement sql? Je ne sais pas comment je devrai voir cela.

Aussi, si j'avais des :

if (isset...)

ça serait du traitement qui irait normalement dans le contrôler?

J'essaie de voir les éléments qui se trouve entre les mains et de les répartir au bon endroit.

 
Par Cyrano  -  Le 15/02/2014 09:37  -  Haut de page  - 

Tu mélanges un peu tout là... tu parles d'une « class singleton pour la connexion » : je me demande si tu sais exactement ce qu'est un singleton ? Et si oui, pourquoi faudrait-il l'utiliser ?

J'ai lu les deux pages que tu indiques. La première est effectivement intéressante parce qu'elle montre une progression d'un code purement procédural avec des répétitions de codes systématiques à un code où on regroupe les doublons dans des fonctions externes et enfin à un code où on regroupe certaines fonctions dans des classes.
Actuellement, si on refait un peu le tour de tout ce que tu as indiqué depuis le début de ce post, tout donne à penser que tu tentes de passer du procédural à la POO avancée avec emploi de design patterns sans maitriser suffisamment les bases de la POO. Ça t'amène à faire des amalgames et à t'engager dans un fouillis de complications. Or je t'ai déjà indiqué deux fois qu'il y a un ordre à suivre dans l'apprentissage.

À ta question si tu avais des :

if (isset...)

Tu peux avoir ça aussi bien dans n'importe quel code, du procédural, dans des classes, n'importe où, même si tu as un système avec des controleurs, des modèles etc...

Tu as montré un bout de code de base que tu veux transformer :

    <?php  

    $db = new PDO('mysql:host=localhost;dbname=ptg;charset=utf8', 'root', '');  
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);  

    $stmt = $db->query('SELECT * FROM artistes');  
    $results = $stmt->fetchAll(PDO::FETCH_OBJ);  

    foreach($results as $r) {  
        echo $r->id.' '.$r->nom.'</br>';  
    }  

    ?>  

Je te propose un exercice : construis un code qui emploierait deux classes : une classe dbConnexion et une classe artistes de façon à ce que le résultat soit exactement le même.
Oublie le MVC et les singletons à ce stade, commence par le commencement et on verra après pour afiner.

 
Par dancom5  -  Le 20/02/2014 04:54  -  Haut de page  - 

Bonsoir Cyrano.

La seule chose qui pourrait convenir, c'est l'apprentissage avec toi,
sur un bout de code quand je voulais portabiliser aux niveaux des
tables et des champs.

Je crois bien que j'ai fini par comprendre le processus des objets.

Une Class pour la connexion à la base de données et une class pour
l'affichage des données en faisant un héritage.

J'ai mis au plus simple pour tout afficher.

    <?php

    define('USER','root');
    define('PASS','');
    define('DSNH',"mysql:host=localhost;dbname=ptg");

    class db{

        private static $_instance;

        public static function pdo_connection(){
                if (!self::$_instance){
                        try{
                                self::$_instance = new PDO(DSNH, USER, PASS);
                                self::$_instance->setAttribute(PDO::ATTR_PERSISTENT,true);
                                self::$_instance->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
                        } catch (PDOException $est){
                                die($est->getMessage());
                        }
                }
                return self::$_instance;
        }

        private function __construct(){
        }

        private function __clone(){
        }

    } 
    ?>

    <?php

    // extention du singleton DB
    class Model extends db {

            private $_conn;

            public function __construct() {
                    $this->_conn = db::pdo_connection();
            }

            public function select() {
                    $stmt = $this->_conn->query("SELECT * FROM artistes");
                    $rows = $stmt->fetchAll(PDO::FETCH_OBJ);
                    return $rows;
            }
    }

    $a = new Model;

    foreach($a->select() as $afficher)
    { echo $afficher->id .'</br>'; }

    ?>

La Class Model va hériter de la connexion à la base de données.
En mettant cette class le plus généraliste possible (je l'ai pas fait ici)
J'aurai pu faire d'autre Class qui hériteraient de la class model.

Je crois que séparer par des fonctions pour ajouter l'affichage selon
le ID et autres champs.

Je crois que l'idéal serait de créer une class affichage avec des méthodes
pour faire différentes manière d'afficher. J'ai pensé objet cette fois-ci.

La partie forearch irait dans un autre fichier.

Les deux class selon moi, ça fait parti du model.

Mais, si y aurait des commandes test comme vérifier avec des isset,
je crois que ça irait dans controleur.

Mon projet de site que je devais faire, j'ai décidé d'utiliser un CMS
Mais, le CMS c'est pour le système d'album photos.

Je continue puisque je veux apprendre à bien faire en PHP.
Et ça peut m'aider à réaliser des choses.

Pour les class, j'ai eu beau chercher, et je ne vois pas autrement
qu'un singleton de connexion pour l'accès à la base de données

Merci pour ton attention sur l'aide que tu m'apporte.
Je l'apprécie. :-)

PS, parfois, j'ai de la difficulté à exprimer ce que je comprends dans
ma tête et ça sort tout croche. On ne peut pas être parfait :-)

 
Par dancom5  -  Le 20/02/2014 06:31  -  Haut de page  - 

...suite

En mettant dans deux fichiers les Class, je pourrais les lier comme ceci:

Fichier index.php:

    <?php

    define('__ROOT__', dirname(__FILE__));

    require_once(__ROOT__.'/dbconn.php');
    require_once(__ROOT__.'/model.php');

    ?>

Je sais qu'il y a une méthode avec un système spécialement pour les Class mais faut juste que je l'apprenne.

 
Par Cyrano  -  Le 20/02/2014 07:05  -  Haut de page  - 

Salut,
voilà, ça commence à prendre bonne tournure : du fichier original, on sépare certaines parties du code et on les déporte dans des classes. Schématiquement, c'est le résultat que j'espérais te voir me montrer.

Il reste maintenant à ajuster certains détails. Tu fais hériter ta classe Model de la classe de connexion : techniquement, ça fonctionne, mais ce n'est pas forcément logique pour autant : autant une classe de connexion est assez générique et doit pouvoir être utilisée dans n'importe quel type d'application, autant ta classe modèle est propre à cette application-ci. Formulé autrement, la classe db se classe dans les librairies, mais la classe modele entre dans la catégorie « classes métier »

Pour arranger ça et faire en sorte que ta classe model dispose des méthodes appropriées, tu peux supprimer l'héritage et remplacer ça par une injection de dépendance.

Reprenons ton code : on va créer d'abord trois fichiers, un fichier de configuration où tu définis les paramètres de connexion, une classe de connexion et une classe pour les artistes. Voyons d'abord les paramètres :

    <?php  
    /**  
     * fichier config.php  
     * Paramètres de connexion à la base de données  
     */  
    define('USER',  'root');  
    define('PASS',  '');  
    define('DSNH',  "mysql:host=localhost;dbname=ptg");  
    ?>  

Comme ça, si tu as besoin de ces paramètres ailleurs, ils restent disponibles partout. Voyons ensuite ta classe de connexion :

    <?php  
    /**  
     * Fichier dbConnexion.php  
     * Classe de connexion à une base de données   
     */  
    class db  
    {  
        private static $_instance;  
        public static function pdo_connection($user, $pass, $dnsh)  
        {  
            if(!self::$_instance)  
            {  
                try  
                {  
                    self::$_instance = new PDO($dsnh, $user, $pass);  
                    self::$_instance->setAttribute(PDO::ATTR_PERSISTENT, true);  
                    self::$_instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  
                }  
                catch(PDOException $est)  
                {  
                    die($est->getMessage());  
                }  
            }  
            return self::$_instance;  
        }  
        private function __construct()  
        {}  
        private function __clone()  
        {}  
    }  
    ?>  

Rien de particulier ici, j'ai repris ton propre code, on ne s'attardera pas dessus, mais note bien la modification au niveau des paramètres lorsqu'on appelle la méthode pdo_connection() : il y a maintenant des paramètres.
Maintenant, on passe à la classe que tu as appelé Model étendant db : ici, on va procéder à des modification : d'abord on fait sauter l'héritage, et on va remplacer ça par une injection de dépendance, on va ensuite la renommer pour qu'elle soit plus parlante quant à sa nature :

    <?php  
    /**  
     * Fichier artiste.php  
     */  
    class artiste  
    {  
        private $_conn;  
        /**  
         * Constructeur  
         * @param db    $cnx    Instance de la classe db  
         */  
        public function __construct($cnx)  
        {  
            $this->_conn = $cnx;  
        }  

        /**  
         * Collecte de la liste de tous les artistes  
         */  
        public function liste()  
        {  
            $stmt = $this->_conn->query("SELECT * FROM artistes");  
            $rows = $stmt->fetchAll(PDO::FETCH_OBJ);  
            return $rows;  
        }  
    }  
    ?>  

Observe les modifications : le constructeur reçoit l'injection de dépendance sous la forme d'un objet de connexion. Comprends bien un truc : cette classe ne connait pas cet objet, tout ce qu'il sais, c'est que ça doit être un objet qui contient certaines méthodes comme query() ou fetchAll() par exemple.

Ok, voyons maintenant comment on transforme le code de base :

    <?php  
    //On effectue l'inclusion des fichiers nécessaires;  
    include 'config.php';  
    include 'dbConnexion.php';  
    include 'artiste.php';  
    // On crée un objet de connexion à la base;  
    $cnx = db::pdo_connection(USER, PASS, DNSH);  
    // On crée un objet pour lister nos artistes en passant un objet de connexion  
    $oArtiste = new artiste($cnx);  
    // On récupère la liste complète des artistes  
    $aListeArtistes = $oArtiste->liste();  
    // On affiche le résultat obtenu.  
    foreach($aListeArtistes as $artiste)  
    {  
        echo($artiste->id ."<br />");  
    }  
    ?>  

Voilà, relis tout ça et analyse, ça devrait se mettre en place tranquillement dans ton esprit : comment on sépare en objets différents et indépendants.

 
Par dancom5  -  Le 20/02/2014 08:15  -  Haut de page  - 

Salut Cyrano.

<?php
// fichier config.inc.php
define('DNSH',"mysql:host=localhost;dbname=ptg");
define('USER','root');
define('PASS','');
?>

<?php
// fichier dbcon.class.php
class dbcon{
    private static $_instance;
    public static function pdo_connection(){
        if (!self::$_instance){
            try{
                            self::$_instance = new PDO(DNSH, USER, PASS);
                            self::$_instance->setAttribute(PDO::ATTR_PERSISTENT,true);
                            self::$_instance->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
            } catch (PDOException $est){
                            die($est->getMessage());
            }
        }
        return self::$_instance;
    }
    private function __construct(){
    }
    private function __clone(){
    }
} 
?>

<?php
// fichier artiste.class.php
class artiste{
    private $_conn;
    public function __construct($cnx){
        $this->_conn = $cnx;
    }
    public function lister(){
        $stmt = $this->_conn->query("SELECT * FROM artistes");
        $rows = $stmt->fetchAll(PDO::FETCH_OBJ);
        return $rows;
    }
}
?>

<?php
// fichier index.php

require_once($_SERVER["DOCUMENT_ROOT"].'/config.inc.php');

function __autoload($class_name) {
        if(file_exists($_SERVER["DOCUMENT_ROOT"] . '/' . strtolower($class_name) . '.class.php')) {
                require_once($_SERVER["DOCUMENT_ROOT"] . '/' . strtolower($class_name) . '.class.php');
        } else {
                throw new Exception("Impossible de charger $class_name.");
        }
}

$cnx = dbcon::pdo_connection(DNSH,USER,PASS);  

$oArtiste = new artiste($cnx);  
$aListeArtistes = $oArtiste->lister();  

foreach($aListeArtistes as $artiste) {  
    echo $artiste->id ."<br />";  
}  

?>

Je vais étudier plus en profondeur ce dont je viens d'apprendre. J'ai mis en fichiers mes nouvelles connaissances. C'est encourageant.

Avec autoload, ça marche bien.

 
Par Cyrano  -  Le 20/02/2014 08:25  -  Haut de page  - 

Ok, tu as ajouté un autoload, c'est effectivement plus pratique.

Mais attention, tu n'as pas appliqué les modifications suggérées quant aux paramètres de connexion dans ta classe dbcon. Je sais bien que la portée des constantes est en principe globale, cependant, ça reste une mauvaise idée dans ce cas : suppose en effet que tu aies une application utilisant deux bases de données distinctes, tu ne pourras alors te connecter que sur une seule, celle définie dans les constantes. Ton système lie trop fortement la classe et les paramètres, et dans ce cas, mettre les paramètres directement en dur dans la classe reviendrait au même.

Pour le reste, je te laisse continuer ton analyse : penses à la manière de répartir des fichiers dans différents répertoires et comment ajuster ça dans ton autoload de façon à ce que tu n'aies pas l'ensemble de tes fichiers en vrac à la racine.

 
Par dancom5  -  Le 02/03/2014 03:44  -  Haut de page  - 

Bonjour Cyrano.

J'ai pas vraiment compris quand vous dites: "paramètres de connexion dans ta classe". Je bogue la dessus. Et aussi sur : "lie trop fortement la classe et les paramètres, et dans ce cas, mettre les paramètres directement en dur dans la classe reviendrait au même".

 
Par Cyrano  -  Le 02/03/2014 09:51  -  Haut de page  - 

Je vais prendre un exemple : imagines une calculatrice de poche.

Normalement, tu inscris un premier chiffre, puis, après avoir sélectionné une opération, tu inscris un second chiffre. Jusque là, tout fonctionne normalement et tu peux ainsi effectuer de nombreuses opérations différentes en inscrivant à chaque fois des chiffres différents. Suppose maintenant qu'au lieu d'indiquer des chiffres, ceux-ci soient déjà écrits en dur dans le programme de la calculatrice : plus rien ne fonctionnera sauf si, et seulement si, les chiffres inscrits en dur correspondent justement à ceux dont tu as besoin.

Les chiffres de l'exemple, ce sont des paramètres, ils varient selon les besoins. Si tu crées une classe dont l'objectif est d'établir une connexion à un serveur de bases de données, il te faudra indiquer des paramètres de connexion. Tu as deux options : soit tu inscris ces paramètres en dur dans la classe, soit tu les transmets à l'instance via le constructeur par exemple. Avec la première option, la classe n'est pas portable et ne pourra servir qu'avec un unique serveur, alors qu'avec la seconde, tu pourras utiliser cette même classe quel que soit le serveur, il suffira simplement à chaque fois d'indiquer avec quels paramètres la connexion devra être établie.

Si tu remonte un tout petit peu plus haut et observes le code que je t'avais proposé, j'avais suggéré ceci :

<?php  
/**  
 * Fichier dbConnexion.php  
 * Classe de connexion à une base de données   
 */  
class db  
{  
    private static $_instance;  
    public static function pdo_connection($user, $pass, $dnsh)  
    {  
        if(!self::$_instance)  
        {  
            try  
            {  
                self::$_instance = new PDO($dsnh, $user, $pass);  
                self::$_instance->setAttribute(PDO::ATTR_PERSISTENT, true);  
                self::$_instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  
            }  
            catch(PDOException $est)  
            {  
                die($est->getMessage());  
            }  
        }  
        return self::$_instance;  
    }  
    private function __construct()  
    {}  
    private function __clone()  
    {}  
}

Regarde la méthode pdo_connection().

 
Par dancom5  -  Le 03/03/2014 09:42  -  Haut de page  - 

Il me reste qu'à organiser le tout en répertoires pour avoir une structure MVC à ce que je vois. Mon fichier artiste.vue.php se trouve être plus mon fichier metier dans le sens qu'il y a une manipulation de la base de fichier (une requête SQL).

Le fichier config.inc.php change pour mettre des variables comme ceci :

    $dnsh = "mysql:host=localhost;dbname=ptg";
    $user = "root";
    $pass = "";

Le fichier index.php ne change pas pour l'instant.

Le fichier dbconn.class.php change comme vous le prosposé

Le fichier artiste.vue.php change pour remplacer les constantes par des variables.
Mais, la variable

$cnx = dbcon::pdo_connection($dnsh,$user,$pass); 

Devrait plutôt se trouver dans la partie métier, comme je n'ai pas réalisé le MVC
encore, il doit se trouver juste avant l'instanciation:

$oArtiste = new artiste($cnx);
 
Par Cyrano  -  Le 03/03/2014 09:53  -  Haut de page  - 

L'idée générale, c'est surtout de faire ce qu'on appelle du code DRY ( Don't Repeat Yourself = Ne vous Répétez pas), c'est à dire d'éviter les répétitions inutiles de code.

Ensuite, une autre bonne pratique consiste à séparer les différentes couches de l'application, le code générique, le code métier, la partie affichage, la partie traitement, etc.. tout ça pour structurer de telle sorte que la maintenance et les éventuels correctifs puissent être effectués très rapidement et efficacement.

Je serais tenté de te dire : oublie le MVC à ce stade, tu n'as actuellement qu'une idée très théorique de ce que c'est et ce niveau de connaissance est très insuffisant pour le moment pour envisager de construire une application répondant convenablement à ce motif de conception. Commence par appliquer les bonnes pratiques, apprends les Design Patterns essentiels et petit à petit, à force de les manipuler, tu sauras quoi faire et comment les mettre en œuvre pour construire une application selon le motif MVC.
Sinon, plus tu vas t'acharner à vouloir tout de suite monter un MVC, plus tu vas t'enliser dans comprendre réellement pourquoi et tu aboutiras à une usine à gaz invraisemblable.

 
Par lavm100  -  Le 22/01/2015 16:58  -  Haut de page  - 

J'ai une question pour toi Cyrano,

Dans un model MVC, si j'ai beaucoup de texte à mettre (ex: règlements, conditions, comment faire, etc...), pour écrire ce texte il n'y a pas d'accès à la bd, je ne veux pas faire plein de echo, alors je le mets ou et comment faire l'output correctement. Je suis loin d'être un expert..

Merci !

 
Par Cyrano  -  Le 22/01/2015 17:09  -  Haut de page  - 

Salut,
tu peux toujours enregistrer ça dans un fichier indépendant, tu pourrais même le pré-formater en HTML dans une variable avec une syntaxe HEREDOC, et dans ce cas, tu fais un include de ce fichier dans la page qui doit l'afficher et tu fais un seul echo avec la variable en question.

    <?php  
    /**  
     * Exemple de texte stocké  
     */  
    $cgv = <<<CODE_HTML  
        <div>  
          <h2>Conditions générales de vente</h2>  
          <p>Toute marchandise achetée doit être payée avant d'être emportée.</p>  
          <p>Et autres blablabla à ton goût ;) ...</p>  
        </div>  

    CODE_HTML;  

Tu enregistre ça par exemple en cgv.phtml (l'extension « phtml » est un classique souvent utilisé pour les templates), et dans le fichier PHP qui construit ta vue, tu auras aloors quelque part :

    include('chemin/vers/mes/fichiers/cgv.phtml');  
    echo($cgv);  

Et c'est tout, pas plus compliqué que ça. J'ajoute que ça marche aussi bien en POO qu'en procédural, et même s'il n'y a pas de MVC, cet aspect n,a aucune espèce d'imortance :)

 
Par lavm100  -  Le 22/01/2015 17:38  -  Haut de page  - 

Merci Cyrano,

Je ne sais pas si j'ai la bonne méthode, mais je faisais ceci:

initialisation

$cComm = '';

dans partout ou j'avais besoin de faire un echo je faisais

$cComm .= '<p>bla bla bla</p>';

return $cComm;

Ensuite je récupérais le $cComm dans ma vue.

 
Par Cyrano  -  Le 22/01/2015 17:44  -  Haut de page  - 

« return » s'utilise dans une fonction, pas en vrac n'importe où, ça doit rester cohérent : on appelle quelque chose, et ce quelque chose retourne un résultat, une valeur ou un ensemble de valeurs. Ce quelque chose doit donc être capable de recevoir un appel : il n'y a que les fonctions ou les méthodes de classes qui peuvent faire ça.

 
Par lavm100  -  Le 22/01/2015 17:53  -  Haut de page  - 

Je sais, tout est dans une fonction

Exemple:
<code>
function csa($nEnvi, $aEnvi)
{
//initialisation

$cComm = '';

//et partout ou j'avais besoin de faire un echo je faisais

$cComm .= '<p>bla bla bla</p>';

return $cComm;
}
</code>

Et dans mon petit contrôleur frontal

<code>
$cComm = csa(parm1,parm2);

require 'Vue/vueaccueil.php';
</code>

Merci !

 
Par Cyrano  -  Le 22/01/2015 17:59  -  Haut de page  - 

Ok, alors dans ce cas c'est bon :)

 
Par lavm100  -  Le 22/01/2015 18:01  -  Haut de page  - 

Ok Merci, tu es super gentil et super rapide à répondre. On se dit à bientôt.

 

Ajouter une réponse à la discussion

Seuls les membres connectés sont autorisés à poster dans les forums !

Identifiez-vous
Join |  ID/MDP? |