/** * Skeleton subclass for representing a row from the 'user' table. * * You should add additional methods to this class to meet the * application requirements. This class will only be generated as * long as it does not already exist in the output directory. */ class Post extends BasePost { public function getAbbrTitle() { return substr($this->title, 0, 15); } } http://propelorm.org/ MVC mercredi 5 septembre 12
/** * Skeleton subclass for representing a row from the 'user' table. * * You should add additional methods to this class to meet the * application requirements. This class will only be generated as * long as it does not already exist in the output directory. */ class Post extends BasePost { public function getAbbrTitle() { return substr($this->title, 0, 15); } } http://propelorm.org/ MVC Métier mercredi 5 septembre 12
class User { public function __construct() { $this->storage = new SessionStorage('SESSION_ID'); } public function setLanguage($language) { $this->storage->set('language', $language); } } $user = new User(); INJECTION DE DÉPENDANCE mercredi 5 septembre 12
class User { public function __construct() { $this->storage = new SessionStorage('SESSION_ID'); } public function setLanguage($language) { $this->storage->set('language', $language); } } $user = new User(); INJECTION DE DÉPENDANCE Dépendance forte mercredi 5 septembre 12
class User { private $storage; public function __construct(StorageInterface $storage) { $this->storage = $storage; } } $storage = new SessionStorage('SESSION_ID'); $user = new User($storage); INJECTION DE DÉPENDANCE Injection mercredi 5 septembre 12
class User { private $storage; public function __construct(StorageInterface $storage) { $this->storage = $storage; } } $storage = new SessionStorage('my_session_name'); $user = new User($storage); INJECTION DE DÉPENDANCE mercredi 5 septembre 12
class User { private $storage; public function __construct(StorageInterface $storage) { $this->storage = $storage; } } $storage = new MemcacheStorage(); $user = new User($storage); INJECTION DE DÉPENDANCE mercredi 5 septembre 12
class User { private $storage; public function __construct(StorageInterface $storage) { $this->storage = $storage; } } $storage = new MemcacheStorage($memcacheClient); $user = new User($storage); INJECTION DE DÉPENDANCE mercredi 5 septembre 12
CLASSLOADER “Autoloading” respectant le standard PSR-0 https://github.com/php-fig/fig-standards/blob/master/accepted/ PSR-0.md COMPOSANTS mercredi 5 septembre 12
CONFIG Gestion avancée de configuration Chargement de fichiers de configuration Mise en cache de la configuration Définition du format de configuration COMPOSANTS mercredi 5 septembre 12
CONFIG Gestion avancée de configuration Chargement de fichiers de configuration Mise en cache de la configuration Définition du format de configuration Multi-source (fichiers, base de données) COMPOSANTS mercredi 5 septembre 12
CONFIG Gestion avancée de configuration Chargement de fichiers de configuration Mise en cache de la configuration Définition du format de configuration Multi-source (fichiers, base de données) Multi-format (YAML, XML, JSON) COMPOSANTS mercredi 5 septembre 12
DEPENDENCYINJECTION use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; $container = new ContainerBuilder(); $loader = new YamlFileLoader($container, new FileLocator(__DIR__)); $loader->load('services.yml'); $manager = $container->get('newsletter_manager'); COMPOSANTS mercredi 5 septembre 12
DEPENDENCYINJECTION use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; $container = new ContainerBuilder(); $loader = new YamlFileLoader($container, new FileLocator(__DIR__)); $loader->load('services.yml'); $manager = $container->get('newsletter_manager'); COMPOSANTS mercredi 5 septembre 12
EVENTDISPATCHER use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\Event; $dispatcher = new EventDispatcher(); $dispatcher->addListener('foo.action', function (Event $event) { // will be executed when the foo.action event is dispatched }); $dispatcher->dispatch('foo.action', new Event()); COMPOSANTS mercredi 5 septembre 12
EVENTDISPATCHER use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\Event; $dispatcher = new EventDispatcher(); $dispatcher->addListener('foo.action', function (Event $event) { // will be executed when the foo.action event is dispatched }); $dispatcher->dispatch('foo.action', new Event()); COMPOSANTS mercredi 5 septembre 12
EVENTDISPATCHER use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\Event; $dispatcher = new EventDispatcher(); $dispatcher->addListener('foo.action', function (Event $event) { // will be executed when the foo.action event is dispatched }); $dispatcher->dispatch('foo.action', new Event()); COMPOSANTS Listener mercredi 5 septembre 12
EVENTDISPATCHER use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\Event; $dispatcher = new EventDispatcher(); $dispatcher->addListener('foo.action', function (Event $event) { // will be executed when the foo.action event is dispatched }); $dispatcher->dispatch('foo.action', new Event()); COMPOSANTS Événement mercredi 5 septembre 12
FINDER use Symfony\Component\Finder\Finder; $finder = new Finder(); $finder->files()->in(__DIR__); foreach ($finder as $file) { // Print the absolute path print $file->getRealpath()."\n"; // Print the relative path to the file, omitting the filename print $file->getRelativePath()."\n"; // Print the relative path to the file print $file->getRelativePathname()."\n"; } COMPOSANTS mercredi 5 septembre 12
FINDER use Symfony\Component\Finder\Finder; $finder = new Finder(); $finder->files()->in(__DIR__); foreach ($finder as $file) { // Print the absolute path print $file->getRealpath()."\n"; // Print the relative path to the file, omitting the filename print $file->getRelativePath()."\n"; // Print the relative path to the file print $file->getRelativePathname()."\n"; } SplFileInfo COMPOSANTS mercredi 5 septembre 12
FINDER use Symfony\Component\Finder\Finder; $finder = new Finder(); $finder->files()->in(__DIR__); foreach ($finder as $file) { // Print the absolute path print $file->getRealpath()."\n"; // Print the relative path to the file, omitting the filename print $file->getRelativePath()."\n"; // Print the relative path to the file print $file->getRelativePathname()."\n"; } COMPOSANTS mercredi 5 septembre 12
FINDER use Symfony\Component\Finder\Finder; $finder = new Finder(); $finder->files()->in(__DIR__); foreach ($finder as $file) { // Print the absolute path print $file->getRealpath()."\n"; // Print the relative path to the file, omitting the filename print $file->getRelativePath()."\n"; // Print the relative path to the file print $file->getRelativePathname()."\n"; } COMPOSANTS mercredi 5 septembre 12
FINDER use Symfony\Component\Finder\Finder; $finder = new Finder(); $finder->files()->in(__DIR__); foreach ($finder as $file) { // Print the absolute path print $file->getRealpath()."\n"; // Print the relative path to the file, omitting the filename print $file->getRelativePath()."\n"; // Print the relative path to the file print $file->getRelativePathname()."\n"; } COMPOSANTS mercredi 5 septembre 12
FINDER Recherche dans plusieurs répertoires Exclusion de répertoire Recherche sur masques de fichiers Recherche par taille COMPOSANTS mercredi 5 septembre 12
FINDER Recherche dans plusieurs répertoires Exclusion de répertoire Recherche sur masques de fichiers Recherche par taille Recherche par date COMPOSANTS mercredi 5 septembre 12
FINDER Recherche dans plusieurs répertoires Exclusion de répertoire Recherche sur masques de fichiers Recherche par taille Recherche par date Tri standard (nom, type) COMPOSANTS mercredi 5 septembre 12
FINDER Recherche dans plusieurs répertoires Exclusion de répertoire Recherche sur masques de fichiers Recherche par taille Recherche par date Tri standard (nom, type) Tri personnalisé (“callback”) COMPOSANTS mercredi 5 septembre 12
FINDER Recherche dans plusieurs répertoires Exclusion de répertoire Recherche sur masques de fichiers Recherche par taille Recherche par date Tri standard (nom, type) Tri personnalisé (“callback”) Compatible avec les “streams” PHP COMPOSANTS mercredi 5 septembre 12
FINDER Recherche dans plusieurs répertoires Exclusion de répertoire Recherche sur masques de fichiers Recherche par taille Recherche par date Tri standard (nom, type) Tri personnalisé (“callback”) Compatible avec les “streams” PHP ... COMPOSANTS mercredi 5 septembre 12
FORM Gestion de formulaires complexes Rendu personnalisable via Twig Validation des données Encore en beta (prévu pour la 2.1) COMPOSANTS mercredi 5 septembre 12
Un Bundle peut contenir : Des extensions pour l’injection de dépendance Des contrôleurs Des gabarits Twig La couche modèle BUNDLES mercredi 5 septembre 12
Un Bundle peut contenir : Des extensions pour l’injection de dépendance Des contrôleurs Des gabarits Twig La couche modèle Tout le nécessaire pour votre application BUNDLES mercredi 5 septembre 12
Feature: buy an article In order to be happy As a consumer I want to be able to buy something Scenario: Given I am on the homepage When I search for "fridge" And I follow "Awesome Fridge" And I add the article to my cart And I follow "checkout" # steps that describe the checkout process Then I should see "Your order is complete!" And I should be happy to have a new fridge CONTRÔLE QUALITÉ mercredi 5 septembre 12
Feature: buy an article In order to be happy As a consumer I want to be able to buy something Scenario: Given I am on the homepage When I search for "fridge" And I follow "Awesome Fridge" And I add the article to my cart And I follow "checkout" # steps that describe the checkout process Then I should see "Your order is complete!" And I should be happy to have a new fridge CONTRÔLE QUALITÉ Step mercredi 5 septembre 12