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 :

Questions sur les services [2.x]


Sujet :

Symfony PHP

  1. #1
    Membre régulier
    Profil pro
    Développeur
    Inscrit en
    Janvier 2010
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Janvier 2010
    Messages : 232
    Points : 112
    Points
    112
    Par défaut Questions sur les services
    Bonjour,

    Débutant sous symfony, en train de travailler sur les services.
    J'essaie d'en comprendre le sens.
    Un service est une classe contenue dans un container. Quelle est alors la différence avec une bibliothèque de classes ? sinon dans le fonctionnement ?
    En lançant la commande container:debug, je vois :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    mailer                                          n/a       alias for swiftmailer.mailer.default
    ...
    session                                         container Symfony\Component\HttpFoundation\Session\Session
    Je comprends bien que mailer et session sont deux services.
    Où apparait leur container, notamment session ? Et pourquoi swiftmailer.mailer.default ? et pas simplement swiftmailer.

    Enfin, dans le fichier ap/config.config.yml,
    on voit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    # Swiftmailer Configuration
    swiftmailer:
        transport: %mailer_transport%
        host:      %mailer_host%
        username:  %mailer_user%
        password:  %mailer_password%
        spool:     { type: memory }
    %mailer est donc le nom du service ?

    puis dans le même fichier :
    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
     
    framework:
        #esi:             ~
        #translator:      { fallback: %locale% }
        secret:          %secret%
        router:
            resource: "%kernel.root_dir%/config/routing.yml"
            strict_requirements: ~
        form:            ~
        csrf_protection: ~
        validation:      { enable_annotations: true }
        templating:
            engines: ['twig']
            #assets_version: SomeVersionScheme
        default_locale:  "%locale%"
        trusted_proxies: ~
        session:         ~
        fragments:       ~
        http_method_override: true
    Dois-je comprendre que form, session, router sont des service natifs du framework ?

    Un grand merci pour vos réponses et désolé si elles sont simplistes.
    Cordialement

  2. #2
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut
    par rapport à une bibliothèque classique le service profite de certains avantages grâce à son contenair.

    1. un service peut être appelé de n'importe ou
    2. c'est le container qui s'occupe d'instancier et ce, une et une seule fois. pour les prochains appels, il renvoi la même instance de l'objet.
    (et donc pour l'initialisation, dans certains cas il est plus judicieux d'initialiser d’éventuels variables par méthode que par le constructeur)
    3. donc pas besoin de require... un simple ->get('nom du service') suffit
    4. le service est instancié seulement si on le sollicite


    d'ailleurs, tu peux très bien utiliser une classe php(lib) externe à Symfony en le transformant en service(quelques manip pour ça) pour que le container s'en occupe et pour ainsi profiter des avantages qu'offrent les services et son container.

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 168
    Points : 219
    Points
    219
    Par défaut
    Citation Envoyé par dukoid Voir le message
    2. c'est le contenair qui s'occupe d'instancier et ce, une et une seule fois. pour les prochains appels, il renvoi la même instance de l'objet.
    (et donc pour l'initialisation, dans certains cas il est plus judicieux d'initialiser d’éventuels variables par méthode que par le constructeur)
    Bonjour, j'apporterais juste une petite modification au point 2.

    Par défaut oui, le scope d'un service est container mais il peut être request (même instance au sein de la même requête) ou prototype (une nouvelle instance a chaque fois que je demande le service).

  4. #4
    Membre régulier
    Profil pro
    Développeur
    Inscrit en
    Janvier 2010
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Janvier 2010
    Messages : 232
    Points : 112
    Points
    112
    Par défaut
    Merci pour cette précision.
    Je ne maîtrise pas bien encore la notion de conteneur.
    Si on prend session, qui est bien un service. Je ne trouve pas dans config.yml le container de session.
    Si j'en crois mon code

    $this étant un controler, controler est le container de session.
    Par contre, come le dit goabonga, on peut récupérer session gràace à request, mais
    pas comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $request->get('session')
    mais comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $request->getSession();
    tout simplement car getSession est une méthode publique de l'objet request et non un container.
    Cette notion de service surprend un peu, mais ça a l'air sympa !
    Merci pour votre aide.

  5. #5
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut
    ok merci pour vos précisions


    1. un service peut être appelé de n'importe ou
    2. - c'est le container qui s'occupe d'instancier et ce, une et une seule fois. pour les prochains appels, il renvoi la même instance de l'objet.
    (et donc pour l'initialisation, dans certains cas il est plus judicieux d'initialiser d’éventuels variables par méthode que par le constructeur)
    - par défaut le scope d'un service est container mais il peut être request (même instance au sein de la même requête) ou prototype (une nouvelle instance a chaque fois que je demande le service).

    3. donc pas besoin de require... un simple ->get('nom du service') suffit.le container s'occupe de tout.
    4. le service est instancié seulement si on le sollicite

    en langage "Objet" on pourrait dire que le container est une sorte de factory qui fait parti de ce qu'on appel un design pattern. (une solution à un problème et/ou une bonne pratique)

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 168
    Points : 219
    Points
    219
    Par défaut
    Citation Envoyé par loustalet Voir le message
    Merci pour cette précision.
    Je ne maîtrise pas bien encore la notion de conteneur.
    Si on prend session, qui est bien un service. Je ne trouve pas dans config.yml le container de session.
    Si j'en crois mon code

    $this étant un controler, controler est le container de session.
    non le service container n'est pas le controller la class Controller dispose des fonctions :
    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
     
      /**
         * Returns true if the service id is defined.
         *
         * @param string $id The service id
         *
         * @return Boolean true if the service id is defined, false otherwise
         */
        public function has($id)
        {
            return $this->container->has($id);
        }
     
        /**
         * Gets a service by id.
         *
         * @param string $id The service id
         *
         * @return object The service
         */
        public function get($id)
        {
            return $this->container->get($id);
        }
    Et le container est injecté dans les controller ....
    Pour assimiler la notion de container et d'ioc je te conseil de regarder le service container de Silex (Pimple).

  7. #7
    Membre expérimenté Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Points : 1 310
    Points
    1 310
    Par défaut
    Hello, j'apporterai moi aussi une petite remarque :

    1. un service peut être appelé de n'importe ou
    C'est pas tout à fait juste : un service peut être appelé par le container de service. Le container est effectivement présent par défaut dans la classe parente Controller (on le voit dans l'exemple de goabonga). Et cette classe Controller est étendue par les contrôleurs générés par Symfony via les commandes consoles par exemple : c'est pour cette raison qu'on y a accès dans tous les contrôleurs (qui étendent de cette classe).

    Mais ce container n'est pas supposé être présent "n'importe où" (dans les repository par exemple).

    Un autre point : tu n'est pas obligé d'injecter le container tout entier pour accéder à tes services. Il est parfois plus judicieux de n'injecter que le service dont tu as besoin par injection de dépendance plutôt que d'injecter tout le container.

    ++

  8. #8
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut
    merci nico pour cette précision


    voici la rectification: (ainsi au final on aura quelque chose de clair sur le fonctionnement des services )
    1. un service peut être appelé de presque n'importe ou
    ( Le container est effectivement présent par défaut dans la classe parente Controller. c'est pour cette raison qu'on y a accès dans tous les contrôleurs (qui étendent de cette classe).
    Mais ce container n'est pas supposé être présent dans les repository par exemple
    ).

    2. - c'est le container qui s'occupe d'instancier et ce, une et une seule fois. pour les prochains appels, il renvoi la même instance de l'objet.
    (et donc pour l'initialisation, dans certains cas il est plus judicieux d'initialiser d’éventuels variables par méthode que par le constructeur)
    - par défaut le scope d'un service est container mais il peut être request (même instance au sein de la même requête) ou prototype (une nouvelle instance a chaque fois que je demande le service).

    3. donc pas besoin de require... un simple ->get('nom du service') suffit.le container s'occupe de tout.

    4. le service est instancié seulement si on le sollicite

    que veux tu dire par injecter le container? dans quel cas? pourquoi? un exemple ?

  9. #9
    Membre expérimenté Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Points : 1 310
    Points
    1 310
    Par défaut
    que veux tu dire par injecter le container? dans quel cas? pourquoi? un exemple ?
    Je suis dans mon contrôleur : j'appelle un service UserManager pour créer un utilisateur. Ce service va créer l'utilisateur puis lui envoyer un mail pour l'informer que son compte a été créé.

    Donc si depuis ce service je veux appeler mon autre service Mailer qui lui s'occupe d'envoyer les mails il y a deux solutions :

    1) J'estime que c'est toujours au container d'appeler les services et je l'injecte dans mon UserManager, pour pouvoir faire à l'intérieur de ce service un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $mailer = $this->container->get('mailer');
    2) J'injecte directement mon service mailler dans UserManager. Et depuis cette classe j'appelle directement Le but étant de réduire le couplage : ta classe UserManager a besoin d'un mailer pour fonctionner, pas d'un service container.

  10. #10
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut
    ok je comprends mieux

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

Discussions similaires

  1. [2.x] Questions sur les services et l'injection de dépendance
    Par bilbi dans le forum Symfony
    Réponses: 2
    Dernier message: 15/06/2012, 12h02
  2. Question sur les services
    Par digofwall dans le forum C#
    Réponses: 7
    Dernier message: 05/11/2010, 02h31
  3. Réponses: 5
    Dernier message: 22/08/2008, 10h59
  4. Questions générales sur les services NT
    Par scougirou dans le forum Windows Serveur
    Réponses: 3
    Dernier message: 16/03/2007, 15h50
  5. Question sur les services windows
    Par bilb0t dans le forum Windows
    Réponses: 8
    Dernier message: 09/11/2005, 15h31

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