Le blog de Noël GUILBERT

blog de noel guilbert

Aller au contenu Aller au menu

jeudi, février 4 2010

symfony live 2010

symfony-live-2010

Je sors ce blog de sa torpeur pour vous rappeler l'évènement symfony de cette année : le symfony live.

Pour la deuxième année consécutive, Sensio Labs, créateur du framework, organise l'évènement. Il se tiendra les 16 et 17 février 2010 à la Cité universitaire de Paris.

Le conclusion de la conférence sera l'occasion pour les participants de découvrir en avant première Symfony 2, la future version du framework.

Deux journées de formations sont également organisées autour de l'évènement : c'est une occasion unique d'être formé par les membres de la core team, ainsi que de participer à une des toutes première formation Git en Europe. Alors inscrivez-vous, il est encore temps!

mardi, juin 30 2009

Utiliser l'injection de dépendance dans un projet Symfony

Fabien à publié aujourd'hui un nouveau composant Symfony : le Dependency Injection Container. J'en profite donc pour publier un petit billet sur l'utilisation de ce composant dans un projet Symfony. Je pars du principe que vous avez déjà un projet Symfony installé, et si ce n'est pas le cas, commencez par la page d'installation.

Dans ce billet, je vais reprendre directement les exemples présents dans la http://components.symfony-project.org/dependency-injection/documentation, à savoir créer un service permettant d'envoyer un mail.

Nous allons donc avoir besoin de deux librairies, à savoir:

  • Dependency injection Container bien évidemment
  • Zend Mail

Prérequis

Pour faire les choses rapidement, on va juste faire un export des librairies dans le repertoire lib/vendor de votre application. Si vous utilisez déjà Subversion avec votre projet, la meilleure façon sera d'ajouter ces deux repository en externals.

$> svn export http://svn.symfony-project.com/components/dependency_injection/trunk/ lib/vendor/dependency_injection
$> svn export http://framework.zend.com/svn/framework/standard/trunk/library/Zend lib/vendor/Zend

Création du Service Container

Tout d'abord, il faut initialiser l'autoloading pour pouvoir utiliser le composant. Ajoutez ces deux lignes dans le fichier

<?php

require_once dirname(__FILE__).'/../lib/vendor/dependency_injection/lib/sfServiceContainerAutoloader.php';
sfServiceContainerAutoloader::register();

Toujours dans ce fichier, nous allons ajouter une méthode initializeServiceContainer() pour initialiser le conteneur de services:

<?php

class ProjectConfiguration extends sfProjectConfiguration
{
  protected
    $serviceContainer;
 
  /* ... */

  protected function initializeServiceContainer()
  {
    $this->serviceContainer = new sfServiceContainerBuilder();
    $loader = new sfServiceContainerLoaderFileYaml($this->serviceContainer);

    if ($this instanceof sfApplicationConfiguration && file_exists($file = sfConfig::get('sf_config_dir').'/container_'.$this->environment.'.yml'))
    {
       $loader->load($file);
    }
    else
    {
      $loader->load(sfConfig::get('sf_config_dir').'/container.yml');
    }
  }

Le composant nous offre la possibilité de charger la configuration en XML ou YAML à travers les classes sfServiceContainerLoaderFileXml ou sfServiceContainerLoaderFileYaml. Dans cet exemple, nous utilisons le format YAML, pour rester cohérent avec les autres fichiers de configuration de Symfony.

La classe sfServiceContainerBuilder sera notre conteneur de services. C'est lui qui sera chargé de d'instancier et de configurer les différents services. Pour charger la configuration, nous demandons ensuite au loader de charger les fichier Yaml pour l'environnement actuel si il y en a un, ou la configuration par défaut le cas échéant (par exemple en mode cli).

Le fichier container.yml est exactement le même que celui de la documentation:

parameters:
  mailer.username: foo
  mailer.password: bar
  mailer.class:    Zend_Mail
 
services:
  mail.transport:
    class:     Zend_Mail_Transport_Smtp
    arguments: [smtp.gmail.com, { auth: login, username: %mailer.username%, password: %mailer.password%, ssl: ssl, port: 465 }]
    shared:    false
  mailer:
    class: %mailer.class%
    calls:
      - [setDefaultTransport, [@mail.transport]]

Ces fichiers ne font rien de plus qu'importer le fichier de configuration par défaut.

C'est à peut prêt tout ce que nous avons besoin pour utiliser l'injection de dépendance. Nous avons juste besoin d'initialiser automatiquement le service container, et d'avoir une méthode permettant d'y accéder.

Dans votre fichier config/ProjectConfiguration.class.php, nous ajoutons une méthode getServiceContainer(), et nous ajoutons l'appel à la méthode initializeServiceContainer() dans la méthode setup() :


<?php

class ProjectConfiguration extends sfProjectConfiguration
{
  /* ... */
  public function setup()
  {
    /* ... */

    $this->initializeServiceContainer();
  }

  public function getServiceContainer()
  {
    return $this->serviceContainer;
  }

/* ... */
}

Pour l'utiliser, c'est très simple. Si vous utiliser le service mail dans une action, c'est désormais assez simple:

<?php

public function executeSendMail(sfWebRequest $request)
{
  $this->mailer = sfApplicationConfiguration::getActive()->getServiceContainer()->mailer;
  $this->mailer->
    setBodyText('This is the text of the mail.')->
    setFrom('somebody@example.com', 'Some Sender')->
    addTo('somebody_else@example.com', 'Some Recipient')->
    setSubject('TestSubject')->
    send();
}

Oui, et alors?

C'est un petit peu ce que je me suis dis la 1ère fois que j'ai entendu parler d'injection de dépendance. Le gros avantage, c'est que désormais on va pouvoir configurer notre service en fonction de chaque environnement. Ça a un gros intérêt lors de l'écriture de tests unitaire par exemple, parce que vous ne voulez peut-être pas recevoir un mail à chaque fois que les tests sont lancés. Pour les tests, il va donc falloir désactiver l'envoi de mail. Sans l'injection de dépendance, il faudrait tester si on est en environnement de test directement dans l'action. Maintenant, il suffira de modifier la configuration, sans avoir à modifier le code.

Customiser la configuration pour l'environnement de test

En général, lors des tests, on écrit des classes qui simulent le comportement de la classe utilisées par l'application (les "Mocks"). C'est assez facile à mettre en place pour les tests unitaires, mais pas toujours évidents lors des tests fonctionnels. Ici, c'est très simple, il suffit d'ajouter un fichier de configuration pour l'environnement de test (config/container_test.yml) :

parameters:
  mailer.class:    Mail_Mock

services:
  mailer: 
    class: %mailer.class%

La classe Mail_Mock ici est très simpliste, elle reprend juste les méthodes utilisés dans notre action, et ne fait aucun traitement :

lib/test/Mail_Mock.class.php

<?php

class Mail_Mock
{
  public function setFrom()
  {
    return $this;
  }

  public function addTo()
  {
    return $this;
  }

  public function setBodyText()
  {
    return $this;
  }

  public function setSubject()
  {
    return $this;
  }

  public function send()
  {
    return true;
  }
}

Conclusion

Ce composant est l'une des pièces maitresse de Symfony 2, et fait entrer le framework dans la cour des grands comme Spring. L'autre gros avantage, c'est qu'il est complétement découplé de Symfony, et donc réutilisable sans avoir besoin du framework.

lundi, mai 25 2009

Un rss pour faire de la veille sur Symfony

Si comme moi vous faites un peu de veille autour de Symfony, ce billet est pour vous.

Il y a quelque temps, j'ai découvert Yahoo! Pipes. Cet outil permet d'aggréger, filtrer et trier plusieurs types de contenu et de réaliser, en autre, un flux RSS.

Voici donc le flux RSS que j'utilise depuis pour rester au courant des dernières actualités.

Les différents flux utilisés:

  • Symfony Planet
  • Delicious
  • technorati
  • Blog Officiel de Symfony
  • Dernières applications publiées sur Symfonians
  • wikio
  • Flickr
  • Google Base

Vous pouvez aussi accéder directement à la version en ligne ici.

Si vous utilisez d'autres sources d'informations, n'hésitez à me les indiquer dans les commentaires, je les ajouterai.

- page 1 de 5