[RESOLU] Qu'est qu'un contrôleur ?

Mammouth du PHP | 790 Messages

19 nov. 2012, 13:57

Avec des mots simple, comment peut on définir un contrôleur ?
Un contrôleur: est il une classe ou une petite procédure ou une fonction ?
Un routeur, je veux dire un code qui crée les chemins de fichier, est il un contrôleur, une classe, une fonction ?

Je pense qu'il y a plusieurs réponses possible a certaines questions mais dans l'enssemble...

merci d'avance...
Les fautes de grammaire et d'orthographe contenu dans mes postes sont sous copyright, vous pouvez les utiliser pour un usage personnelle mais vous ne devrez en aucun cas les utiliser a des fins commercial sans une autorisation écrite de ma part.

Mammouth du PHP | 790 Messages

19 nov. 2012, 14:06

Quand on dit contrôleur frontale, qu'elle est se nature, que doit il faire ?
pour ma part, il vérifie la présence de $_GET['module'] et son contenu et si ça ne va pas, il dirige sur un module ACCUEIL: cela vous parait il correct ?
ensuite, j'ai un 2eme contrôleur pour la page qui vérifie la présence de $_GET['page'] et son contenu et si ça ne va pas il dirige sur un page ACCUEIL du module demander: est-ce correct aussi ?
Les fautes de grammaire et d'orthographe contenu dans mes postes sont sous copyright, vous pouvez les utiliser pour un usage personnelle mais vous ne devrez en aucun cas les utiliser a des fins commercial sans une autorisation écrite de ma part.

Eléphant du PHP | 127 Messages

19 nov. 2012, 14:32

Bonjour Juliette,

un contrôleur est une classe dont le rôle est de gérer une requête et d'envoyer une réponse. Il est le liant entre la requête, la logique métier (ce pour quoi on l'appelle) et la réponse. C'est pourquoi on lui donne le rôle de coordinateur. En MVC pur, le contrôleur ne fait rien d'autre qu'appeler une couche "métier" et de renvoyer des données de réponse dans un format donné (HTML, JSON, XML, etc.).

Ce qu'on appelle contrôleur frontal est le contrôleur qui reçoit la requête, qui la route et qui renvoie la réponse. Souvent, ce contrôleur frontal dispatche l'action vers le contrôleur réellement ciblé. Note que cette notion de contrôleur frontal est optionnelle.

Pour résumé voici un petit récap des étapes que suit une requête.

0. envoi de la requête par le client
1. réception de la requête par le serveur sur le fichier index.php (souvent via réécriture d'URL)
2. instanciation du framework et appelle du router
3. routing de la requête sur un contrôleur (dispatch)
4. exécution de la logique métier (appelle à la BDD, traitements, etc)
5. instanciation d'une vue à laquelle le contrôleur passe les données issues de la logique métier
6. création de la réponse via la vue
7. envoi de la réponse au client
8. réception de la réponse par le client

Un schéma de ce genre reprend ces notions : http://lemalesaint.fr/wp-content/upload ... -php-3.png (pas de moi).

Mammouth du PHP | 790 Messages

19 nov. 2012, 14:51

un contrôleur est une classe dont le rôle est de gérer une requête et d'envoyer une réponse
nous parlons bien d’une requête http ?
Ce qu'on appelle contrôleur frontal est le contrôleur qui reçoit la requête, qui la route et qui renvoie la réponse.
Donc le code suivant effectue le bon travail ?
if (!isset($_GET['module']) || empty($_GET['module'])) {
    
    $module = new Module(1);
} 
elseif (isset($_GET['module'])) {
    $connex = new Connex();
    $_GET['module'] = (int) $_GET['module'];
    $critere = array($_GET['module']);
    // on cherche si un id existe
    $requete = "SELECT id_module FROM modules WHERE id_module = ?";
    $nbModule = $connex->compte($critere, $requete);
    $nb = $nbModule;
    if ($nb === 1) {
        // on crée l'objet du module demander
        $module = new Module($_GET['module']);
    } 
    else {
        $module = new Module(1);
    }
} 
else {


    $module = new Module(1);
}
0. envoi de la requête par le client
1. réception de la requête par le serveur sur le fichier index.php (souvent via réécriture d'URL)
2. instanciation du framework et appelle du router
3. routing de la requête sur un contrôleur (dispatch)
4. exécution de la logique métier (appelle à la BDD, traitements, etc)
5. instanciation d'une vue à laquelle le contrôleur passe les données issues de la logique métier
6. création de la réponse via la vue
7. envoi de la réponse au client
8. réception de la réponse par le client
Pour ce qui est de l'ordre des étapes, il me semble être sur la bonne route mais pour l'image, je ne peut pas trop te dire, il faut que j'en comprenne plus que ça :D

merci beaucoup !!!
Les fautes de grammaire et d'orthographe contenu dans mes postes sont sous copyright, vous pouvez les utiliser pour un usage personnelle mais vous ne devrez en aucun cas les utiliser a des fins commercial sans une autorisation écrite de ma part.

Avatar du membre
Mammouth du PHP | 1609 Messages

19 nov. 2012, 15:12

Pour une application web il s'agit bien d'une requête HTTP et ton code ressemble bien à celui d'un contrôleur.

EDIT pour le commentaire de nhachet. Il a tout à fait raison. Personnellement je dirai dans ce cas que ton code ressemble plus au front controller et qu'il sagit de la partie routage et que la class Module serait le controller. A voir ce qu'il y a dedans.

Sinon tu peux te passer du premier if :
if(isset($_GET['module']) && !empty($_GET['module'])) {
  $connex = new Connex();
  $_GET['module'] = (int) $_GET['module'];
  $critere = array($_GET['module']);
  // on cherche si un id existe
  $requete = "SELECT id_module FROM modules WHERE id_module = ?";
  $nbModule = $connex->compte($critere, $requete);
  $nb = $nbModule;
  if ($nb === 1) {
    // on crée l'objet du module demander
    $module = new Module($_GET['module']);
  }
  else {
    $module = new Module(1);
  }
}
else {
  $module = new Module(1);
}
Modifié en dernier par Saian le 19 nov. 2012, 15:27, modifié 2 fois.
Développeur web depuis + de 20 ans

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

19 nov. 2012, 15:19

Salut,

Dans le contexte web il s'agit généralement d'une requête http, mais ce principe est valable quelques soit l'environnement du moment que tu utilise un modèle MVC.

MVC : est un modèle, une "norme" a suivre pour faire quelque chose de propre avec une méthode éprouvée (comme un maçon utilise du ciment et pas de la patte a modèler XD).

Pour ce quid est de ton code non, dans un contrôleur tu ne devrais avoir accès au sgbd.
Si tes pages sont en base ok, dans ce cas tu a une classe qui se charge d'aller chercher les bonnes infos et elle retour e un objet avec.

Petit complément sur l'info de nhachet assez complète : la partie métier c'est le M de MVC. Le modèle de ton application (reliée au sgbd ;) )


@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 127 Messages

19 nov. 2012, 15:20

Dans le modèle MVC, une requête HTTP est souvent transposée en POO avant d'être passée au contrôleur. Cela permet de rester dans une logique POO de bout en bout.

Le code que tu donnes correspond au routeur. Le routeur prend la requête, l'analyse et en déduit un contrôleur.
Le contrôleur frontal englobe ces traitements. Voici un exemple en pseudo-code PHP :

Fichier index.php :
<?php
require 'FrontController.php';
$frontController = new FrontController(new Request());
$response = $frontController -> response();
echo $response -> display();
Fichier Frontcontroller.php :
<?php
class Frontcontroller {
 private $response;
 public function __construct(Request $request) {
  $router = new Router($request);
  $this -> response = $router -> dispatch();
 }
Fichier Router.php :
class Router {
 public function __construct(Request $request) {
  $this -> request = $request;
 }
 public function dispatch() {
  // instancie et appelle le contrôleur, il existe d'autre technique voir le design patterns Factory
  $controllerName = $this-> getController();
  $actionName = $this-> getAction();
  $controller = new $controllerName();
  return $controller -> $action($this -> request);
 }
}

Mammouth du PHP | 790 Messages

19 nov. 2012, 15:35

Merci Saian :mrgreen:
Moogli, Nhachet: vous avez raison mais en fait vous allez trop vite: la j'en suis a construire un système que je trouve logique et simple a mettre en oeuvre...
Comme je n'ai pas une grande expérience avec mvc j'ai tendance a faire du procédurale et a faire ma classe avec après :mrgreen:

donc je continue:
ensuite viens le contrôleur de page:
<?php
/* * ***************************************************************************
 * Initialisation de la page avec $_GET['page']
 * ************************************************************************** */
if (!isset($_GET['page']) || empty($_GET['page'])) {
    /* si $_GET n'existe pas ou est vide */
    $fichier = 'accueil';
    $nom_page = 'accueil';
    $vue = 'modules/' . $module->nomModule() . '/vues/accueil.php';
} elseif (isset($_GET['page']) && (!empty($_GET['page']))) {
    /**
     * Si $_GET existe et qu'il n'est pas vide: inclusion de routeur.php 
     * il contient toutes les routes des fichiers présents dans son module
     */
    include 'modules/' . $module->nomModule() . '/controler/routeur.php';
} else {
    /* Si rien ne correspond, je dirige vers module site page accueil */
    $fichier = 'accueil';
    $nom_page = 'accueil';
    $vue = 'modules/' . $module->nomModule() . 'vues/accueil.php';
}

/* création de l'objet page */
$page = new Page($fichier);
?>
qui inclu ( include 'modules/' . $module->nomModule() . '/controler/routeur.php'; ) si $_GEt['page'] est comme il le doit:
contenu de routeur.php
<?php

if ($_GET['page'] == 'accueil'
        OR $_GET['page'] == 'presentation'
        OR $_GET['page'] == 'liste-blog') {
    $fichier = $_GET['page'];
    $nom_page = $_GET['page'];
    $vue = 'modules/' . $module->nomModule() . '/vues/' . $fichier . '.php';
} else {
    $fichier = 'accueil';
    $nom_page = 'accueil';
    $vue = 'modules/' . $module->nomModule() . '/vues/' . $fichier . '.php';
}
?>


voila, ça fonctionne exactement comme je le veux mais ca ne s'utilise pas comme je le veux...
avant de revenir a la poo, je voudrais savoir si la procédure est bonne ?
Les fautes de grammaire et d'orthographe contenu dans mes postes sont sous copyright, vous pouvez les utiliser pour un usage personnelle mais vous ne devrez en aucun cas les utiliser a des fins commercial sans une autorisation écrite de ma part.

Eléphant du PHP | 127 Messages

19 nov. 2012, 15:48

Si je comprends bien ton code, chaque module a son propre routeur.
Je te conseille de faire un seul routeur générique qui irait lire un fichier de configuration de ton module :

Exemple :
'modules/' . $module->nomModule() . '/config/routes.xml'; 
Ici je mets du XML, mais rien n'empêche de mettre du INI, YAML ou du PHP.

Dès lors, il suffit de contrôler que ton module est actif et que la route décrit dans son routes.xml correspond à la route courante. Ton Frontcontroller utilisera le routeur qui lui-même ira lire les fichiers config de chaque module pour instancier le bon module/contrôleur.

Voici un exemple de fichier de config possible (format ROUTE : CONTROLLER->ACTION):
[module]
/module1

[controllers]
/controller1/action1 : Controller1Controller->action1
/controller1/action2 : Controller1Controller->action2
/controller2/action : Controller1Controller2->action
Et voici des exemples d'actions pour que ce soit plus parlant :
[module]
/blog

[controllers]
/articles : ArticlesController->lister
/articles/ajouter : ArticlesController->ajouter
/articles/[id]/commentaires : CommentairesController->listerParArticle

Mammouth du PHP | 790 Messages

19 nov. 2012, 16:01

Si je comprends bien ton code, chaque module a son propre routeur.
oui, c'est bien ça et c’était ma question suivante, comment simplifier le routeur ?
Bon, le tu me parle de quelque chose que je ne connais pas alors si tu as un tuto n'hésite pas, je cherche quand même, merci :D
Les fautes de grammaire et d'orthographe contenu dans mes postes sont sous copyright, vous pouvez les utiliser pour un usage personnelle mais vous ne devrez en aucun cas les utiliser a des fins commercial sans une autorisation écrite de ma part.

Avatar du membre
Mammouth du PHP | 1609 Messages

19 nov. 2012, 16:05

La suite me parait un peu compliquée. Tu dois pouvoir simplifier tout ça.
Pourquoi as-tu une classe module et une classe page ?
Ton système de routage devrait être capable d'instancier le bon contrôleur et d'appeler la bonne action pour au final avoir quelque chose du style :
$module = new $module();
$module->{$action}();
$module->renderView();
Développeur web depuis + de 20 ans

Mammouth du PHP | 790 Messages

19 nov. 2012, 16:17

ça y est je ne suis plus #-o
Bon, au vu de ce que j'affiche, pouvez vous me donner dans l'ordre les priorités ?
Les fautes de grammaire et d'orthographe contenu dans mes postes sont sous copyright, vous pouvez les utiliser pour un usage personnelle mais vous ne devrez en aucun cas les utiliser a des fins commercial sans une autorisation écrite de ma part.

Mammouth du PHP | 790 Messages

19 nov. 2012, 16:43

ok, après avoir lu 2 ou 3 truc, je comprend que je dois tous recommencer en me basant en premier lieu sur un système de routes ?
Les fautes de grammaire et d'orthographe contenu dans mes postes sont sous copyright, vous pouvez les utiliser pour un usage personnelle mais vous ne devrez en aucun cas les utiliser a des fins commercial sans une autorisation écrite de ma part.

Avatar du membre
Mammouth du PHP | 1609 Messages

19 nov. 2012, 16:59

Déjà tu peux simplifier ton système en t'imposant quelques règles de nommage.
Par exemple pour un module article avec des actions (pages) liste et detail, tu pourrais nommer la classe module article (tu la fais hériter de module) et les vues des actions liste.php et detail.php.
Ainsi avec les paramètre module = article et page = liste tu as toutes les infos qu'il te faut.

La class article :
class article extends module {
  public function liste() {
    // le code de la page
  }

  public function detail() {
    // le code de la page
  }
}
Le routage et l'appel de l'action du contrôleur (en simplifié sans les tests) :
$module = new $_GET['module']();
$module->{$_GET['page']}();
Ensuite il faut que tu ajoutes un système de transfert des variables entre l'action et la vue pour en faire le rendu.

Voilà c'est une piste pour ton développement. Et au fait tu fais ça dans quel cadre ? c'est un sujet d'études ?
Développeur web depuis + de 20 ans

Mammouth du PHP | 790 Messages

19 nov. 2012, 17:14

ok, je commence a mieux cerner le principe, j'ai déjà recréer une archi et je reprend tous a zero en commençant pas ces foutus routes :D
Et au fait tu fais ça dans quel cadre ? c'est un sujet d'études ?
la soif d'apprendre, je n'i ai d'utilité prévu mais comme je veux apprendre, que j'ai le temps et que je sais ce que je veux dans un cms a l'origine fait pour les intégrateurs, je tente de le faire... et si j'y arrive, je dis bien "SI" alors je l'utiliserais...
Les fautes de grammaire et d'orthographe contenu dans mes postes sont sous copyright, vous pouvez les utiliser pour un usage personnelle mais vous ne devrez en aucun cas les utiliser a des fins commercial sans une autorisation écrite de ma part.