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

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

Langage PHP Discussion :

MVC, inclure les vues et les modèles [PHP 5.0]


Sujet :

Langage PHP

  1. #1
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 051
    Points : 1 638
    Points
    1 638
    Par défaut MVC, inclure les vues et les modèles
    Bonjour,

    Codant en PHP 5 depuis quelques mois, je suis en train de développer un nouveau site avec le pattern MVC. La logique du pattern je la comprend sans problème, j'ai trouver de nombreux tutos sur le net, mais au final, chacun adapte le pattern comme il l'entend.

    Ce que j'ai du mal à voir avec les exemples du net (qui sont souvent simpliste dans le fonctionnement), c'est comment en fonction de l'action dans l'url (GET), on récupère les données puis on affiche la bonne vue.

    Voici une structure que j'ai commencé à faire :
    le contrôleur index.php :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    <?php
    session_start();
    ob_start();
    //$_SESSION = array();
    // Fichier de configuration de l'application
    include 'global/config.php';
     
    #region Haut du site
    include $Config['vues']['vueHeader'];
    include $Config['vues']['vueBandeauLogo'];
    include $Config['vues']['vueMenu'];
    #endregion
     
    #region fonctions appelées
    include $Config['fonctions']['Redirection'];
    #endregion
     
    #region Class appelées
    include $Config['class']['Connexion'];
    include $Config['class']['Membres'];
    #endregion
     
    // On créé une connexion à la base de données
    $instanceBDD = new ConnexionBDD();
    $connexion = $instanceBDD->Se_connecter();
     
    // On vérifie que l'action GET renvoie bien le paramètre 'action'
    if(!empty($_GET['action']) && in_array($_GET['action'],$Config['liste_actions']))
    {
    	// Si l'action permet de s'inscrire ou de se connecter
    	if(empty($_SESSION['id_user']) && empty($_SESSION['nom_utilisateur']))
    	{
    		if($_GET['action'] === $Config['liste_actions']['tryConnecter'])
    		{
    			include $Config['actions']['tryConnecter'];
    			if(!empty($resultat))
    				echo $resultat; // On affiche le message si l'utilisateur tente de modifier l'url mais qu'il est déjà connecté
    		}
    		else if($_GET['action'] === $Config['liste_actions']['tryInscrire'])
    		{
    			include $Config['fonctions']['VerifierMail'];
    			include $Config['actions']['tryInscrire'];
    			if(!empty($resultat))
    				echo $resultat; // On affiche le message si l'utilisateur tente de modifier l'url mais qu'il est déjà connecté
    		}
    		else
    		{
    			echo Redirection(false,null);
    		}
    	}
    	else
    	{
    		if($_GET['action'] === $Config['liste_actions']['accueil'])
    		{
    			echo "Titi";
    		}
    		else
    		{
    			echo Redirection(true,'accueil');
    		}
    	}
    }
    else
    {
    	// On vérifie que l'utilisateur n'et pas modifié l'url et qu'il doive se reconnecter (ou bugguer !)
    	if(!empty($_SESSION['id_user']) && !empty($_SESSION['nom_utilisateur']))
    	{
    		echo Redirection(true,'accueil');
    	}
    	else
    	{
    		include $Config['vues']['vueFormInscription'];
    		include $Config['vues']['vueFormConnexion'];
    	}
    }
    ob_end_flush();
    // Footer du site situé en bas
    include $Config['vues']['vueFooter'];
    Je n'inclues pas le code des vus pour pas surcharger le poste. Le fichier config comprend seulement le tableau avec les différents fichiers à charger
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    <?php
    	// configuration de php
    	ini_set("register_globals","off");
    	//ini_set("display_errors","off");  
    	ini_set("expose_php","off");
     
    	$Config['fonctions'] = array('VerifierMail'=>'scripts/verifMail.php',
    								 'Redirection'=>'scripts/redirection.php');
     
    	$Config['vues'] = array('vueFormInscription'=>'vues/accueil_non_connecter/formInscrire.php',
    							'vueFormConnexion'=>'vues/accueil_non_connecter/formConnexion.php',
    							'vueHeader'=>'vues/generique/header.php',
    							'vueMenu'=>'vues/generique/menu.php',
    							'vueBandeauLogo'=>'vues/generique/bandeau.php',
    							'vueFooter'=>'vues/generique/footer.php');
     
    	$Config['class'] = array('Connexion'=>'class/classConnexion.php',
    							 'Membres'=>'class/classMembres.php');
     
    	$Config['actions'] = array('tryInscrire'=>'modeles/accueil_non_connecter/inscription.php',
    							   'tryConnecter'=>'modeles/accueil_non_connecter/connexion.php');
     
    	$Config['liste_actions'] = array('tryInscrire'=>'tryInscrire',
    									 'tryConnecter'=>'tryConnecter',
    									 'accueil'=>'accueil',);
     
    ?>
    Seulement voilà, si je fais comme ca, j'ai l'impression de mélanger les actions, les vues, les données ... Si j'inclus automatiquement en haut mes vues (header, bandeau, ...) et traite les actions au milieu, ma fonction Redirection($param1,$param2), qui est un seul header location, m'affichera une erreur car du code HTML a été généré avant. Je passe par les fonctions de cache, mais je trouve pas ca terrible.

    Il manque surement des informations sur le code, pour sa compréhension mais dans l'idée, comment récupérer les données en fonction de l'action dans l'url, mais afficher également les vues au bon moment ? Car là j'incluerais bien le code de l'action, puis en suivant la vue, mais je trouve ca étonnant ...

    Quelqu'un aurait un exemple MVC très clair, sans complication ? J'ai déjà passer en revu les tutos de developpez, notamment :
    http://tahe.developpez.com/web/php/mvc/?page=controleur
    Mais je le trouve quand même pas très clair pour débuter en MVC.

    Merci d'avance
    Règle N° 1 : Si tout va bien, ne touchez à rien.

  2. #2
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Y'a quelque chose qui ne va pas du tout avec ton front-controller: on dirait qu'il a beaucoup trop de responsabilités.

    Voici un front-controller typique:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <?php
    require_once "config.php";
    Application::run();
    En bref, ce n'est pas le rôle du front-controller de gêrer les session, les utilisateurs ou encore d'initialiser la BDD. Utiliser des hashmap pour la configuration, les routes ou encore l'autoload est une bonne idée mais toute la logique d'utilisation de ces données de config devrait être encapsulée dans une classe de service.

    Cette classe de service doit être capable d'intepreter les paramètres de l'URL pour trouver le contrôleur et l'action à invoquer (typiquement, Classe::methode pour rester simple).
    Le contrôleur doit alors à son tour invoquer un service et balancer les résultats à la vue.
    C'est vrai qu'il y a beaucoup de façon d'implémenter le pattern MVC et le front-controller mais cette dernière reste de loin la plus utilisée.

    Si ça te branche, tu peux regarder comment php-axiom implémente le front-controller (/application/webroot/index.php) et gêre le routage (voir la classe axRouter) ça te donnera peut être des idées. Tu peux aussi te jeter dans la doc de Zend ou Symphony ou Lithium, sur le principe, ça reste la même chose

  3. #3
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 051
    Points : 1 638
    Points
    1 638
    Par défaut
    Merci pour ta réponse je vais regarder tout les liens.

    Seulement, en zyeutant rapidement les liens, cela me semble difficile à appréhender pour débuter en MVC, mais je vais approfondir.

    Mais finalement, tous les tutos qu'on voit sur le net sur MVC (developpez y compris pour quelques tutos), où ils ont un main.php principal, qui sert de controler, et ensuite des actions if pour savoir quelle action on a, ce n'est pas vraiment les bonnes méthodes ? Car c'est toujours plus simple avec un exemple concrêt d'application, mais je ne trouve pas. Du moins je trouve des exemples MVC, mais la plupart me semble pas correct, ou très bordel pour bien appréhender le pattern

    Merci
    Règle N° 1 : Si tout va bien, ne touchez à rien.

  4. #4
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Je n'ai pas choisi une méthode basée sur un paramètre action mais par reconnaissance d'URL par regexp, ce qui autorise une plus grande flexibilité - en fait, il n'y a plus besoin de décrire les règles de réécriture d'URL au niveau d'Apache mais simplement au niveau de la politique de routage de l'application - je me suis volontairement inspiré du fonctionnement de Lithium sur ce point.

    Utiliser un paramètre action reste cependant tout à fait valide, c'est moins flexible mais beaucoup plus simple.

  5. #5
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 051
    Points : 1 638
    Points
    1 638
    Par défaut
    Je vais partir sur la méthode avec le mot clé action pour commencer. Lorsque je serais plus alaise avec la technique, je passerais sur la tienne

    En lisant beaucoup de tuto hier, j'ai bien compris que le front controler devait juste lancer l'application, donc le controler. Le controleur, rattaché à une classe s'occupe de gérer les actions à traiter, puis d'y afficher les vues adéquates.

    Je me suis donc fait une classe controleur avec certaines méthodes : connexionBDD, getAction (celle qui récupère l'action dans l'url, sinon renvoi vers l'accueil si rien est spécifier), un getVue(appelé par getAction() pour y afficher la bonne vue).

    Finalement je me demande si le plus simple, dans mon fichier de config serait pas de créer un tableau par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $Config['action']['nom_action'] = array('vue'=>'nomVue','modele'=>'nom_modele','classAUtiliser'=>'nomclasseN');
    Finalement en fonction de l'action, je aurais exactement quelle est la vue, les classes à charger, les modeles pour récupérer les données etc ... Est-ce une méthode viable ou pas du tout ?

    Ce qui pourrait me chagriner, serait si une vue ou classe doit intervenir plusieurs fois, ca va faire doublon ...
    Règle N° 1 : Si tout va bien, ne touchez à rien.

  6. #6
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Pour les routes, tu aurais meilleur compte de faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $Config['actions'] = array(
        'foo' => 'FooController::index',
        'bar' => 'FooController::bar',
    );
    Ce n'est pas le rôle de la route de déterminer la vue à afficher, c'est le contrôleur qui doit la déterminer.

    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class FooController {
     
        public static function index () {
            $a = 1;
            $b = 2;
            include "foo_index.html.php";
        }
     
        public static function bar () {
            $c = 3;
            include "foo_bar.html.php"
        }
    }
    Je me suis donc fait une classe controleur avec certaines méthodes : connexionBDD
    Là encore, c'est pas le rôle du contrôleur d'initialiser la connection BDD, c'est le bootstrap qui doit faire ça.

  7. #7
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 051
    Points : 1 638
    Points
    1 638
    Par défaut
    J'avoue avoir un peu de mal avec cette notion.

    Je n'ai pas l'habitude d'utiliser foo et bar, finalement que représente ces noms ? fonctions et variables ?

    Finalement l'action détermine seulement la fonction à appeler dans le contrôleur ? Car avant d'afficher une vue, il faut que j'appelle le bon modèle également ... ou tu inclues le modèles dans le fichier de vue ?

    Tu connais un site qui présenterais cet exemple ? Car même en reprenant mes cours de DUT, ils utilisent des fonctions getVues, getRequeteUser(), getModele(),... qui m'embrouille plutôt qu'autre chose car je commence à m’imprégner d'une méthode qui ne serait pas bonne si j'ai bien compris.

    Merci en tout cas. Quand je comprendrais la base, ca ira
    Règle N° 1 : Si tout va bien, ne touchez à rien.

  8. #8
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    'foo' et 'bar' sont la traduction anglophone de 'toto' et 'titi', on en mets généralement dans les exemples quand on sait pas quoi mettre comme nom

    Finalement l'action détermine seulement la fonction à appeler dans le contrôleur ? Car avant d'afficher une vue, il faut que j'appelle le bon modèle également ... ou tu inclues le modèles dans le fichier de vue ?
    1. le front-controlleur détermine la route
    2. la route détermine le contrôleur et l'action
    3. l'action invoque les traitements métiers/modèles
    4. enfin l'action appelle la vue

    Après, que tu choisisse de tout mettre dans la route pour que tout soit au même endroit, ça peut se comprendre, tu fais ton implem comme ça t'arrange au final. Le principal c'est d'arriver à segmenter correctement les fonctionnalités et à conserver une certaine cohérence.

    Concernant l'inclusion, c'est beaucoup plus facile si tes métiers / modèles sont des classes, tu peux alors les charger à la demande avec l'autoloader (initialisé au moment du bootstrap).

    ils utilisent des fonctions getVues, getRequeteUser(), getModele()
    Peut être mais à quel niveau ces méthodes sont-elles utilisées ?

  9. #9
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 051
    Points : 1 638
    Points
    1 638
    Par défaut
    Je ne connaissais pas l'autoloader, en effet ca me parait une bonne méthode pour l'inclusion automatique.

    Cependant, tu sais où je pourrais trouver une petite source avec l'exemple que tu m'illustres depuis le début ? Car j'y vois assez clair pour le moment, mais un exemple visuel serait plus simple pour appréhender la chose

    Sinon il me semblait que le front controler lancer juste l'application, hors la il choisit la "route". Finalement la route c'est quoi concrètement ? Car je pensais que c'était l'action, mais apparemment non.

    Car dans ma logique, c'est on récupère l'action de l'URL, on appel le bon contrôleur, on charge le modèle puis on affiche la vue.

    Merci en tout cas
    Règle N° 1 : Si tout va bien, ne touchez à rien.

  10. #10
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Sinon il me semblait que le front controler lancer juste l'application, hors la il choisit la "route". Finalement la route c'est quoi concrètement ? Car je pensais que c'était l'action, mais apparemment non.
    En réalité, le front-controller ne détermine pas la route, il délègue cette tâche au routeur (ce qui revient globalement au même )

    Concrètement une route est une structure de données permettant de faire la liaison entre les paramètres reçus et l'action à effectuer.

    Cependant, tu sais où je pourrais trouver une petite source avec l'exemple que tu m'illustres depuis le début ? Car j'y vois assez clair pour le moment, mais un exemple visuel serait plus simple pour appréhender la chose
    Heu, j'ai rien qui me viens à l'esprit sinon des exemples plutôt complexes, tu peux t'inspirer des classes d'axiom au moins pour la logique.

  11. #11
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 051
    Points : 1 638
    Points
    1 638
    Par défaut
    Merci pour tes réponses.

    Finalement j'ai été convaincu par l'utilité des framework pour coder vite et bien. Malgrè le fait qu'ils soient un peu plus lourd que le framework maison, je vais partir sur la solution Symfony 2, qui me sera porteur pour le futur de toute façon.

    Je passe en résolu.

    Merci !
    Règle N° 1 : Si tout va bien, ne touchez à rien.

  12. #12
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Investir dans des connaissance n'est jamais perdu

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MVC] Partie variable sur toutes les vues
    Par djmic dans le forum Langage
    Réponses: 5
    Dernier message: 13/06/2015, 17h32
  2. Les vues dans le modèle relationnel objet
    Par r_thelord dans le forum Décisions SGBD
    Réponses: 2
    Dernier message: 10/12/2010, 19h01
  3. Les index et les vues oracle
    Par kariba dans le forum Oracle
    Réponses: 13
    Dernier message: 18/07/2006, 09h42
  4. [DB2] Question sur les index et les vues
    Par ahoyeau dans le forum DB2
    Réponses: 1
    Dernier message: 14/03/2005, 08h30

Partager

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