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

Symfony PHP Discussion :

Contrôleur générique [2.x]


Sujet :

Symfony PHP

  1. #1
    Membre régulier Avatar de flutz
    Homme Profil pro
    Ingénieur d'études et développement
    Inscrit en
    Juin 2010
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingénieur d'études et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 52
    Points : 70
    Points
    70
    Par défaut Contrôleur générique
    Bonjour à tous.

    J'effectue la même action au début de chaque méthode de l'ensemble des controllers afin de vérifier certaines si la session est active, serveur en maintenance, action autorisée... (si c'est le cas j'effectue une redirection vers une page spécifique) et aussi pour rafraichir quelques données de l'utilisateur.

    Pour facilité la chose j'ai créé une classe qui étend Controller et qui effectue mes actions, ainsi l'ensemble de mes controllers étendent cette classe et n'ont qu'à appeler une méthode et gérer le retour.

    Mais j'aimerais faire encore plus simple et éviter ces 2 lignes répétitives de code pour chaque controller, et savoir s'il est possible avec Symfony2 de ne pas écrire ce code mais qu'il soit exécuter automatiquement au début de chaque méthode (il m'est impossible de faire ça dans le constructeur car je ne peux pas récupérer le container, d'après ce que j'ai lu c'est parce qu'il est créé après le constructeur).

    Merci d'avance pour vos réponses.
    Il y a souvent confusion entre les geeks, les nolifes, et les
    nerds.

  2. #2
    Membre habitué
    Profil pro
    Développeur Web
    Inscrit en
    Avril 2010
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2010
    Messages : 141
    Points : 157
    Points
    157
    Par défaut
    Je te conseille de te renseigner sur les services.

  3. #3
    Membre régulier Avatar de flutz
    Homme Profil pro
    Ingénieur d'études et développement
    Inscrit en
    Juin 2010
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingénieur d'études et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 52
    Points : 70
    Points
    70
    Par défaut
    Merci de ta réponse, je vais chercher de ce côté.
    Je les utilise déjà un peu mais pas du tout pour ça (et c'est surtout copier coller du tuto de la fermeduweb).
    Il y a souvent confusion entre les geeks, les nolifes, et les
    nerds.

  4. #4
    Membre régulier Avatar de Alcide_
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juin 2008
    Messages : 79
    Points : 114
    Points
    114
    Par défaut
    Je ne connais pas bien Symfony mais je pencherais plutôt pour les Events.

    Voici quelques éléments de réponse pour un équivalent de sf1 sfEvents::preExecute() dans sf2 :


  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Février 2009
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 66
    Points : 82
    Points
    82
    Par défaut
    Comme souvent la réponse est sur le site de symfony:

    http://symfony.com/doc/current/cookb...r_filters.html

    Il te faudra maitriser les events et les services mais en suivant le cookbook c'est très simple à mettre en place.

  6. #6
    Membre régulier Avatar de flutz
    Homme Profil pro
    Ingénieur d'études et développement
    Inscrit en
    Juin 2010
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingénieur d'études et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 52
    Points : 70
    Points
    70
    Par défaut
    Merci beaucoup à vous 2, je regarderais ça ce soir
    Il y a souvent confusion entre les geeks, les nolifes, et les
    nerds.

  7. #7
    Membre régulier Avatar de flutz
    Homme Profil pro
    Ingénieur d'études et développement
    Inscrit en
    Juin 2010
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingénieur d'études et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 52
    Points : 70
    Points
    70
    Par défaut
    Merci à vous ça fonctionne nickel, le mini tutoriel http://www.tribulations.eu/articles/...-symfony2.html linker par Alcide_ est très bien fait et permet d'avoir ce que je voulais!

    Derrière il suffit de créer un controller générique qui est appeler par l'ensemble des Controllers du projet et qui implémente la méthode preExecute (ou une autre suivant le nom que vous lui donné).

    Petit truc en passant pour si certaines personnes tombent sur ce post :
    Pour récupérer dans cette méthode preExecute le paramètre que vous donnez à votre controller :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $params = $request->get('_route_params');
    Et ensuite vous récupérez le paramètre en faisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if (array_key_exists('monParam', $params))
    {
    	$monParam = $params['monParam'];
    }
    Merci de votre aide!
    Il y a souvent confusion entre les geeks, les nolifes, et les
    nerds.

  8. #8
    Membre régulier Avatar de flutz
    Homme Profil pro
    Ingénieur d'études et développement
    Inscrit en
    Juin 2010
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingénieur d'études et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 52
    Points : 70
    Points
    70
    Par défaut
    Ah par contre j'oubliais, dans l'exemple il n'y a pas la redirection, donc voici l'exemple pour faire ensuite une redirection :

    Alors vous aller avoir besoin de cette classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    use Symfony\Component\HttpKernel\Controller\ControllerResolver;
    Elle permet de générer un callable (un controller quoi).

    Et donc le code est tout simple (mais pas simple à trouver sur le net^^) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    // Création de l'instance du résolver
    $controllerResolver = new ControllerResolver();
    // On récupère la request
    $request = new Request();
    // On set dans la request la valeur _controller avec l'action que l'on souhaite exécuter (désolé c'est ici donc une redirection interne, on ne peut pas renvoyer de réponse avec l'event FilterControllerEvent, il faudrait sinon renvoyer une erreur et catcher l'event de l'erreur et setter la réponse dans ce nouvelle évent...)
    $request->attributes->set('_controller', 'Flz\LgcCoreBundle\Controller\MainController::homeAction');
    // Et enfin on set le controller avec  le nouveau créé à partir de la request que l'on vient de mettre à jour      	$event->setController($controllerResolver->getController($request));
    J'espère que ce bout de code vous sera utile =).
    Il y a sans doute une autre façon de faire mais je ne la connais pas.

    Inconvénient majeur : impossibilité d'utiliser $this dans ce cas dans le controller:/
    Il y a souvent confusion entre les geeks, les nolifes, et les
    nerds.

  9. #9
    Membre régulier Avatar de flutz
    Homme Profil pro
    Ingénieur d'études et développement
    Inscrit en
    Juin 2010
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingénieur d'études et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 52
    Points : 70
    Points
    70
    Par défaut
    Au final après quelques heures passée là-dessus, la seule solution que j'ai trouvée (pas très propre à mon goût mais qui a le mérite de fonctionner) c'est :

    Code config.yml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    services:
      controller.pre_execute_listener:
        class: Projet\MonBundle\Listener\MonListener
        tags:
          - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
          - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse }
          - { name: kernel.event_listener, event: kernel.exception, method: onKernelException }

    Code MonListener.php : 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
     
    <?php
    namespace Projet\MonBundle\Listener; 
     
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Symfony\Component\HttpKernel\HttpKernelInterface; 
    use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
    use Symfony\Component\HttpFoundation\RedirectResponse;
    use \Exception;
     
    // Le nom de la classe est à votre discrétion
    class ControllerListener 
    {
    	// Sur exception
    	public function onKernelException(GetResponseForExceptionEvent $event)
    	{
    		// Recupération de l'exception
    		$exception = $event->getException();
     
    		if (get_class($exception) === 'Projet\MonBundle\Exception\MyException');
    		{
    			$response = new RedirectResponse('Votre action');
     
    			$event->setResponse($response);
    		}
    	}
     
    	// Après controller
    	public function onKernelResponse(FilterResponseEvent $event)
    	{
    		// Faire quelque chose... (Ici on a accès à la response le problème ne se pose pas)
    	}
     
    	// Avant controller
    	public function onKernelController(FilterControllerEvent $event) 	
    	{
    		// Récupération de l'event 	
    		if(HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) 
    		{
    			// Récupération du controller    
    			$_controller = $event->getController();
    			if (isset($_controller[0]))
    			{
    				$controller = $_controller[0];
    				// On vérifie que le controller implémente la méthode preExecute
    				if(method_exists($controller, 'preExecute'))
    				{
    					$redirection = $controller->preExecute();
     
    					if ($redirection !== null)
    					{
    						throw new MonException($redirection);
    					}
    				}
    			}
    		}
    	}
    }

    Code MainController.php : 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
     
    <?php
     
    namespace Projet\MonBundle\Controller;
     
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
     
    class MainController extends Controller
    {
    	/**
    	 * Fonction à exécuter avant toute action.
    	 */
    	function preExecute()
    	{
    		// Faire quelque chose avant l'execution du controller et retourner une valeur qui permettra le test dans le listener
    	}
    }

    Classe d'exception qui sert uniquement à être sur qu'on n'est pas sur une vrai exception

    Code MyException.php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    <?php
    namespace Projet\MonBundle\Exception;
     
    class MyException extends \Exception
    {
     
    }

    Il ne reste plus qu'à étendre l'ensemble de vos Controller par la MainController et les actions tout sera fait automatiquement =)

    Si vous avez des suggestions pour faire quelque chose de plus propre je suis preneur!
    Je suis sur qu'il y a moyen d'éviter de passer par une exception mais comment...
    Je suis malheureusement encore noob en php
    Il y a souvent confusion entre les geeks, les nolifes, et les
    nerds.

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

Discussions similaires

  1. Algorithmes génériques pour affichage de primitives 2D.
    Par Selenite dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 02/01/2005, 20h20
  2. [Generics] Classe générique
    Par norkius dans le forum Langage
    Réponses: 4
    Dernier message: 29/10/2004, 15h57
  3. classe date générique ?
    Par lili_bzh dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 07/09/2004, 10h59
  4. taille d'objet générique
    Par Heimdall dans le forum C
    Réponses: 7
    Dernier message: 01/07/2004, 18h00
  5. caractère générique utilisable dans strcmp
    Par barthelv dans le forum C
    Réponses: 9
    Dernier message: 01/08/2003, 16h54

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