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 :

Explication : Bundle, Service et Configuration [Trucs & Astuces]


Sujet :

Symfony PHP

  1. #1
    Membre actif

    Homme Profil pro
    Concepteur d'applications web
    Inscrit en
    Avril 2003
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Concepteur d'applications web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2003
    Messages : 102
    Par défaut Explication : Bundle, Service et Configuration
    Bonjour,

    comme je viens de comprendre comment on faisait pour ajouter des éléments de configuration à son bundle, je tenais à expliquer rapidement le fonctionnement.

    Les pré-requis sont de connaitre la notion de Bundle, et la notion de Service proposées par Symfony2.

    Pour créer son bundle, il est possible de passer par la console via :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    php console generate:bundle --namespace=Package/myBundle --format=yml
    Ensuite on crée une classe de service. Si on veut qu'elle accède au ServiceContainer on peut faire ceci :
    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
     
    class myService
    {
        protected $_container;
        public function setContainer(Symfony\Component\DependencyInjection\Container $container)
        {
            $this->_container = $container;
        }
     
        public function whatever()
        {
            // par exemple : accès au service request
            $this->_container->get('request');
        }
    }
    Mais pour que ça marche, il faut injecter automatiquement le container. Pour cela on passe par l'injection de dépendance et le fichier Resources/config/services.xml
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
        <parameters>
            <parameter key="package_my.myservice.class">Package\myBundle\myService</parameter>
        </parameters>
     
        <services>
            <service id="package_my.myservice" class="%package_my.myservice.class%">
                <call method="setContainer">
                     <argument type="service" id="service_container" />
                </call>
            </service>
        </services>
    De fait Symfony2 se charge d'instancier la classe myService et de lui injecter le serviceContainer via la méthode setContainer. On aurait aussi pu choisir de passer le serviceContainer en paramètre du constructeur de la classe de service. Pour cela il faut l'implémenter dans la classe, et supprimer les noeuds call du fichier services.xml afin de ne laisser que le noeud argument sous le noeud service.

    Votre service est désormais accessible depuis n'importe quel action de controller ou autre service disposant du serviceContainer.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    //via une action
    ...
    $this->get('package_my.myservice');
     
    //via une classe
    ...
    $this->myContainer->get('package_my.myservice');
    Maintenant vous souhaitez que votre classe myService dispose d'une (ou plusieurs) propriété.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class myService
    {
        // nb de resultat a renvoyer
        protected $_nbResult;
     
        public function __construct($nbResult)
        {
            $this->_nbResult = $nbResult;
        }
    }
    Et bien là encore l'injection de dépendance va nous être utile :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    ...
        <services>
            <service id="package_my.myservice" class="%package_my.myservice.class%">
                <argument>15</argument>
                <call method="setContainer">
                     <argument type="service" id="service_container" />
                </call>
            </service>
        </services>
    L'argument ayant pour valeur 15 va donc être passé comme paramètre au constructeur de ma classe.

    Oui mais voilà, on souhaite aussi que ce paramètre soit modifiable. Pour cela on va extraire la valeur du noeud argument et
    utiliser le système de configuration. Il faut alors créer un fichier config.yml dans le répertoire suivant de votre bundle :
    Resources\config\config.yml
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    package_my:
        nbresult: 22
    Puis modifier le fichier de services :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    ...
        <services>
            <service id="package_my.myservice" class="%package_my.myservice.class%">
                <argument>%package_my.nbresult%</argument>
                <call method="setContainer">
                     <argument type="service" id="service_container" />
                </call>
            </service>
        </services>
    Dans ce cas, on demande au framework de charger la configuration du bundle et on indique également que la class myService depend d'un paramètre de configuration
    %package_my.nbresult%

    C'est là que ça se gâte un peu. Tout dépend ce que vous avez dans votre répertoire DependancyInjection de votre bundle.
    Si vous avez une classe de Configuration et une classe d'Extension vous êtes dans le cas le plus compliqué, mais également le plus puissant.

    Le fichier de Configuration permet de controller le contenu du fichier de configuration. Vous allez ainsi définir son contenu via le tree builder :
    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
     
    // classe de configuration
    ...
        public function getConfigTreeBuilder()
        {
            $treeBuilder = new TreeBuilder();
            $rootNode = $treeBuilder->root('package_my');
     
            $rootNode
                ->children()
                    ->scalarNode('nbresult')->defaultValue(10)->end()
                ->end()
            ;
     
            return $treeBuilder;
        }
    On pourrait également vérifier le type de donnée (ici un entier), mais dans notre exemple j'ai juste mis une valeur par défaut au cas où le fichier de configuration ne serait pas remplit.
    (Regardez deplus prêt le TreeBuilder pour plus d'information sur son fonctionnement).

    Et maintenant il faut modifier la classe d'Extension afin de charger le fichier de configuration, mais également le fichier de services, et de définir les paramètres nécessaires.
    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
     
    // classe de configuration
    ...
        public function load(array $configs, ContainerBuilder $container)
        {
    		// charge le contenu du fichier de configuration et gère sa conformité via le TreeBuilder
            $configuration = new Configuration();
            $config = $this->processConfiguration($configuration, $configs);
     
    		// charge le fichier services.yml
            $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
            $loader->load('services.xml');
     
    		// injecte les paramètres 
            $container->setParameter('package_my.nbresult', $config['nbresult']);
        }
    Et voilà, pas besoin de faire d'import depuis le fichier de configuration principal app/config/config.yml
    Ca devrait fonctionner.

  2. #2
    Membre averti
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Février 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef de projet en SSII

    Informations forums :
    Inscription : Février 2007
    Messages : 37
    Par défaut
    @rebolon

    Merci pour ce tuto ! Même si je commence à bien connaître SF, une explication de plus ne fait jamais de mal


  3. #3
    Membre actif

    Homme Profil pro
    Concepteur d'applications web
    Inscrit en
    Avril 2003
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Concepteur d'applications web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2003
    Messages : 102
    Par défaut
    yep, plus on a de ressources, plus vite les développeurs s’approprieront le framework.

Discussions similaires

  1. [2.x] Service, Bundle et configuration
    Par Feesh dans le forum Symfony
    Réponses: 5
    Dernier message: 29/11/2011, 10h14
  2. Configuration Service et Droit d'accés
    Par yosthegost dans le forum Delphi
    Réponses: 21
    Dernier message: 29/06/2006, 10h01
  3. [Configuration] Lancer Arreter un service via php
    Par sebeni dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 14
    Dernier message: 24/01/2006, 14h43
  4. Réponses: 4
    Dernier message: 09/09/2005, 12h59

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