(Meine) Wahrheit über. Symfony. Timon Schroeter. www.php-schulung.de



Similar documents
Symfony2 and Drupal. Why to talk about Symfony2 framework?

Chris van Daele / / QuestBack, Köln. Laravel 5 Framework. The PHP Framework for Web Artisans

Citrix NetScaler Best Practices. Claudio Mascaro Senior Systems Engineer BCD-Sintrag AG

Drupal 8. Core and API Changes Shabir Ahmad MS Software Engg. NUST Principal Software Engineser PHP/Drupal

Services, Dependency Injection, and Containers, Oh my!

A Tour of Silex and Symfony Components. Robert

SPICE auf der Überholspur. Vergleich von ISO (TR) und Automotive SPICE

Documentum Developer Program

Agile Web Development Liip.ch. Introduction to. Lukas Kahwe some content graciously stolen from Yoav

A Comparative Study on Vega-HTTP & Popular Open-source Web-servers

How does Drupal 7 Work? Tess Flynn, KDØPQK

Übersetzerbau in der Industrie: CacaoVM

VSTO 3.0 In Action mit Outlook Lars Keller netcreate OHG

PASS Deutschland e.v. Regionalgruppe Köln/Bonn/Düsseldorf

The Components Book Version: master

repositor.io Simple Repository Management Jürgen Brunk München, 03/2015

Brauche neues Power Supply

Braindumps.C questions

Tobias Flohre codecentric AG. Ein Standard für die Batch- Entwicklung JSR-352

Certified PHP/MySQL Web Developer Course

Eucalyptus User Console Guide

MS Enterprise Library 5.0 (Logging Application Block)

Building Better Controllers Symfony Live Berlin Benjamin Eberlei

elprolog MONITOR-WebAccess Operation Manual

Practical Guided Tour of Symfony

Symfony2: estudo de caso IngressoPrático

Orchestrating Distributed Deployments with Docker and Containers 1 / 30

Glassfish, JAVA EE, Servlets, JSP, EJB

Drupal CMS for marketing sites

Entites in Drupal 8. Sascha Grossenbacher Christophe Galli

CommVault Simpana 7.0 Software Suite. und ORACLE Momentaufnahme. Robert Romanski Channel SE

Onset Computer Corporation

WESTERNACHER OUTLOOK -MANAGER OPERATING MANUAL

ULTEO OPEN VIRTUAL DESKTOP OVD WEB APPLICATION GATEWAY

MASTERTAG DEVELOPER GUIDE

Magento Search Extension TECHNICAL DOCUMENTATION

AJAX SSL- Wizard Reference

Open Text Social Media. Actual Status, Strategy and Roadmap

Komplettschutz für den Mittelstand

AUD17 Versions- und Änderungsmanagement, Audit trails und Disaster Recovery in Produktionsanlagen mit

Jonathan Worthington Scarborough Linux User Group

Migrating into Drupal 8

Designing and Implementing a Server Infrastructure MOC 20413

und die Java-Welt Florian

Deep Freeze and Microsoft System Center Configuration Manager 2012 Integration

What s really under the hood? How I learned to stop worrying and love Magento

Mink Documentation. Release 1.6. Konstantin Kudryashov (everzet)

HOBOlink Web Services V2 Developer s Guide

Here is a quick diagram of the ULV SSO/Sync Application. Number 3 is what we deal with in this document.

Benchmark Performance Test Results for Magento Enterprise Edition

Introduction to Ingeniux Forms Builder. 90 minute Course CMSFB-V6 P

Using Filter as JEE LoadBalancer for Enterprise Application Integration(EAI)

Sitemap. Component for Joomla! This manual documents version 3.15.x of the Joomla! extension.

PHPUnit and Drupal 8 No Unit Left Behind. Paul Mitchum

Spring Design ScreenShare Service SDK Instructions

Introducing Apache Pivot. Greg Brown, Todd Volkert 6/10/2010

Flowpack Single sign-on Server Documentation

Cisco Configuration Professional Workshop

RFC's und Internet- Drafts mit URN-Bezug in Zusammenhang mit der Definition von Namen. Nik Klever FB Informatik - FH Augsburg klever@fh-augsburg.

PROFESSIONAL. Node.js BUILDING JAVASCRIPT-BASED SCALABLE SOFTWARE. Pedro Teixeira WILEY. John Wiley & Sons, Inc.

Data Warehousing Metadata Management

Data Warehousing Metadata Management

phpservermon Documentation

Schöll MOC Installing and Configuring Windows Server 2012

Microsoft Certified IT Professional (MCITP) MCTS: Windows 7, Configuration ( )

GlassFish v3. Building an ex tensible modular Java EE application server. Jerome Dochez and Ludovic Champenois Sun Microsystems, Inc.

Cloud Performance Group 1. Event. 14. Januar 2016 / Matthias Gessenay (matthias.gessenay@corporatesoftware.ch)

Tableau Server Trusted Authentication

DIPLOMA IN WEBDEVELOPMENT

Getting Started with Tableau Server 6.1

Microsoft Windows PowerShell v2 For Administrators

SAP Business Objects Business Intelligence platform Document Version: 4.1 Support Package Data Federation Administration Tool Guide

Website Pros Templates v1.0. Database Template Overview

DB2 z/os und IBM DataStudio

AnyWeb AG

Module developer s tutorial

Expert PHP 5 Tools. Proven enterprise development tools and best practices for designing, coding, testing, and deploying PHP applications.

Evil (Maven) Snapshots. Dr. Halil-Cem Gürsoy G+

Java Server Pages combined with servlets in action. Generals. Java Servlets

Data Management Applications with Drupal as Your Framework

Java Servlet 3.0. Rajiv Mordani Spec Lead

WW INFO-02 Wonderware Historian Best Practices

Everything you ever wanted to know about Drupal 8*

Resources You can find more resources for Sync & Save at our support site:

A Linux/Unix Operating System, or Windows Vista/7 with Cygwin installed;

Rochester Institute of Technology. Finance and Administration. Drupal 7 Training Documentation

How To Use Mts Bondspro From A Computer To A Trading System

Magento Test Automation Framework User's Guide

Cyclope Internet Filtering Proxy. - Installation Guide -

Configuring a Jetty Container for SESM Applications

Transcription:

(Meine) Wahrheit über Symfony

Timon!= Timon

Schulung, Coaching, Beratung

Version 4.2 (2002) OOP? register_globals?

http://doitandhow.com/2012/07/16/fun-colored-spaghetti/

OOP

C++

C++ HPC

C++ fortran HPC

C++ fortran HPC Matlab

professionell entwickeln rumbasteln

TDD

TDD unit

TDD unit OOP + DI

Version 2.0 (2011)

professionell entwickeln rumbasteln

Forms Validation TWIG uvm.

Forms Validation TWIG Dependency Injection Container uvm. Event Dispatcher

Was sind die Kennzeichen dieser Paradigmen? Imperativ Prozedural Objektorientiert 23

Was sind die Kennzeichen dieser Paradigmen? Imperativ Sequenz, Schleife, Verzweigung 24

Was sind die Kennzeichen dieser Paradigmen? Imperativ Sequenz, Schleife, Verzweigung Prozedural Funktionen die alle global verfügbar sind 25

http://doitandhow.com/2012/07/16/fun-colored-spaghetti/

Was sind die Kennzeichen dieser Paradigmen? Imperativ Prozedural Sequenz, Schleife, Verzweigung Funktionen die alle global verfügbar sind Objektorientiert Objekte, Eigenschaften, Methoden usw. 27

Was sind die Kennzeichen dieser Paradigmen? Imperativ Prozedural Sequenz, Schleife, Verzweigung Funktionen die alle global verfügbar sind Objektorientiert Objekte, Eigenschaften, Methoden usw. Funktionen in abgegrenzten Kontexten verfügbar 28

http://www.spieltischshop.de/lego-soft.html

Was sind die Kennzeichen dieser Paradigmen? Imperativ Prozedural Sequenz, Schleife, Verzweigung Funktionen die alle global verfügbar sind Objektorientiert Objekte, Eigenschaften, Methoden usw. Funktionen in abgegrenzten Kontexten verfügbar 30

Was sind die Kennzeichen dieser Paradigmen? Imperativ Prozedural Sequenz, Schleife, Verzweigung Funktionen die alle global verfügbar sind Objektorientiert Objekte, Eigenschaften, Methoden usw. Funktionen in abgegrenzten Kontexten verfügbar feste Abhängigkeiten zwischen Klassen 31

Was sind die Kennzeichen dieser Paradigmen? Imperativ Prozedural Sequenz, Schleife, Verzweigung Funktionen die alle global verfügbar sind Objektorientiert Objekte, Eigenschaften, Methoden usw. Funktionen in abgegrenzten Kontexten verfügbar feste Abhängigkeiten zwischen Klassen OOP mit Dependency Injection 32 Instanzen variabel kombinierbar (Schraubendreher)

33

wiederverwendbar unit-testbar Großteil der Codebasis 34

nicht wiederverwendbar nicht unit-testbar Minimum an Code wiederverwendbar unit-testbar Großteil der Codebasis 35

Dependency Injection 36

DI Dependency Injection 37

Structure of the next slides Code example: DI for generic PHP classes Code example: DI in Symfony 2 38 You are here

<?php namespace Acme\FeedBundle\Service\FeedAggregator Why is this class use Guzzle\Http\Client; difficult to unit test? use Acme\Logger\XmlLogger; class FeedAggregator { private $client; private $logger; public function construct () { $this->client = new Client(); $this->logger = new XmlLogger(); public function retrievefeed ($baseurl, $path) { $request = $this->client->setbaseurl($baseurl)->get($path); $response = $request->send(); if (200!= $response->getstatuscode()) { $this->logger->log('could not get: '.$baseurl.$path); return null; return $response->getbody(); //... 39

<?php namespace Acme\FeedBundle\Service\FeedAggregator Why is this class use Guzzle\Http\Client; difficult to unit test? use Acme\Logger\XmlLogger; class FeedAggregator { private $client; private $logger; public function construct () { What if we want unit tests to run fast without waiting for the network? $this->client = new Client(); $this->logger = new XmlLogger(); public function retrievefeed ($baseurl, $path) { $request = $this->client->setbaseurl($baseurl)->get($path); $response = $request->send(); if (200!= $response->getstatuscode()) { $this->logger->log('could not get: '.$baseurl.$path); return null; return $response->getbody(); //... 40

<?php namespace Acme\FeedBundle\Service\FeedAggregator What if we Why is this class use Guzzle\Http\Client; ever want to difficult to unit test? use Acme\Logger\XmlLogger; class FeedAggregator { private $client; private $logger; use a different HTTP client? public function construct () { What if we want unit tests to run fast without waiting for the network? $this->client = new Client(); $this->logger = new XmlLogger(); public function retrievefeed ($baseurl, $path) { $request = $this->client->setbaseurl($baseurl)->get($path); $response = $request->send(); if (200!= $response->getstatuscode()) { $this->logger->log('could not get: '.$baseurl.$path); return null; return $response->getbody(); //... 41

<?php namespace Acme\FeedBundle\Service\FeedAggregator What if we Why is this class use Guzzle\Http\Client; ever want to difficult to unit test? use Acme\Logger\XmlLogger; class FeedAggregator { What if we $client; private private ever want to$logger; usepublic a different function logger class? use a different HTTP client? construct () { What if we want unit tests to run fast without waiting for the network? $this->client = new Client(); $this->logger = new XmlLogger(); public function retrievefeed ($baseurl, $path) { $request = $this->client->setbaseurl($baseurl)->get($path); $response = $request->send(); if (200!= $response->getstatuscode()) { $this->logger->log('could not get: '.$baseurl.$path); return null; return $response->getbody(); //... 42

<?php namespace Acme\FeedBundle\Service\FeedAggregator What if we Why is this class use Guzzle\Http\Client; ever want to difficult to unit test? use Acme\Logger\XmlLogger; class FeedAggregator { What if we What if we $client; private private ever want to ever want to$logger; use a different HTTP client? use a construct different usepublic a different function log format? logger class? () { What if we want unit tests to run fast without waiting for the network? $this->client = new Client(); $this->logger = new XmlLogger(); public function retrievefeed ($baseurl, $path) { $request = $this->client->setbaseurl($baseurl)->get($path); $response = $request->send(); if (200!= $response->getstatuscode()) { $this->logger->log('could not get: '.$baseurl.$path); return null; return $response->getbody(); //... 43

<?php namespace Acme\FeedBundle\Service\FeedAggregator What if we Why is this class use Guzzle\Http\Client; ever want to difficult to unit test? use Acme\Logger\XmlLogger; class FeedAggregator { What if we What if we $client; private private ever want to ever want to$logger; use a different HTTP client? use a construct different usepublic a different function log format? logger class? () { What if we want unit tests to run fast without waiting for the network? $this->client = new Client(); $this->logger = new XmlLogger(); if we want unit tests to run fast public function retrievefeed What ($baseurl, $path) { $request = $this->client->setbaseurl($baseurl)->get($path); without logging? $response = $request->send(); if (200!= $response->getstatuscode()) { $this->logger->log('could not get: '.$baseurl.$path); return null; return $response->getbody(); //... 44

<?php namespace Acme\FeedBundle\Service\FeedAggregator What if we Why is this class use Guzzle\Http\Client; ever want to difficult to unit test? use Acme\Logger\XmlLogger; class FeedAggregator { What if we What if we $client; private private ever want to ever want to$logger; use a different HTTP client? use a construct different are () usepublic a different function { What if we want unit tests to run fast Dependencies pulled. logreplacing format? requires refactoring logger class? without waiting for the network? => $this->client = new Client(); => Dynamic replacing (e.g. for $this->logger = new XmlLogger(); testing) is impossible if we want unit tests to run fast public function retrievefeed What ($baseurl, $path) { $request = $this->client->setbaseurl($baseurl)->get($path); without logging? $response = $request->send(); if (200!= $response->getstatuscode()) { $this->logger->log('could not get: '.$baseurl.$path); return null; return $response->getbody(); //... 45

<?php namespace Acme\FeedBundle\Service\FeedAggregator Dependencies use Guzzle\Http\Client; use Acme\Logger\XmlLogger; are pulled. class FeedAggregator { private $client; private $logger; public function construct () { $this->client = new Client(); $this->logger = new XmlLogger(); public function retrievefeed ($baseurl, $path) { $request = $this->client->setbaseurl($baseurl)->get($path); $response = $request->send(); if (200!= $response->getstatuscode()) { $this->logger->log('could not get: '.$baseurl.$path); return null; return $response->getbody(); //... 46

<?php namespace Acme\FeedBundle\Service\FeedAggregator Dependencies use Guzzle\Http\ClientInterface; use Acme\Logger\LoggerInterface; are pushed. class FeedAggregator { private $client; private $logger; public function construct(clientinterface $client, LoggerInterface $logger) { $this->client = $client; $this->logger = $logger; public function retrievefeed ($baseurl, $path) { $request = $this->client->setbaseurl($baseurl)->get($path); $response = $request->send(); if (200!= $response->getstatuscode()) { $this->logger->log('could not get: '.$baseurl.$path); return null; return $response->getbody(); //... 47

<?php namespace Acme\FeedBundle\Service\FeedAggregator Dependencies use Guzzle\Http\ClientInterface; use Acme\Logger\LoggerInterface; class FeedAggregator { private $client; Class private $logger; on are pushed. only depends interfaces public function construct(clientinterface $client, LoggerInterface $logger) { $this->client = $client; $this->logger = $logger; public function retrievefeed ($baseurl, $path) { $request = $this->client->setbaseurl($baseurl)->get($path); $response = $request->send(); if (200!= $response->getstatuscode()) { $this->logger->log('could not get: '.$baseurl.$path); return null; return $response->getbody(); //... 48

<?php namespace Acme\FeedBundle\Service\FeedAggregator Dependencies use Guzzle\Http\ClientInterface; use Acme\Logger\LoggerInterface; class FeedAggregator { private $client; Class private $logger; on only depends interfaces are pushed. Implementations are injected at runtime public function construct(clientinterface $client, LoggerInterface $logger) { $this->client = $client; $this->logger = $logger; public function retrievefeed ($baseurl, $path) { $request = $this->client->setbaseurl($baseurl)->get($path); $response = $request->send(); if (200!= $response->getstatuscode()) { $this->logger->log('could not get: '.$baseurl.$path); return null; return $response->getbody(); //... 49

<?php namespace Acme\FeedBundle\Service\FeedAggregator Dependencies use Guzzle\Http\ClientInterface; use Acme\Logger\LoggerInterface; class FeedAggregator { private $client; Class private $logger; on only depends interfaces are pushed. Implementations are injected at runtime public function construct(clientinterface $client, LoggerInterface $logger) { $this->client = $client; $this->logger = $logger; Easy to replace, even dynamically (for testing) public function retrievefeed ($baseurl, $path) { $request = $this->client->setbaseurl($baseurl)->get($path); $response = $request->send(); if (200!= $response->getstatuscode()) { $this->logger->log('could not get: '.$baseurl.$path); return null; return $response->getbody(); //... 50

<?php namespace Acme\FeedBundle\Service\FeedAggregator Dependencies use Guzzle\Http\ClientInterface; use Acme\Logger\LoggerInterface; class FeedAggregator { private $client; Class private $logger; on only depends interfaces are pushed. Implementations are injected at runtime public function construct(clientinterface $client, LoggerInterface $logger) { $this->client = $client; $this->logger = $logger; Easy to replace, even dynamically (for testing) public function retrievefeed ($baseurl, $path) { $request = $this->client->setbaseurl($baseurl)->get($path); $response = $request->send(); if (200!= $response->getstatuscode()) On the level of the class, { $this->logger->log('could not get: '.$baseurl.$path); You are now experts for return null; Dependency Injection. return $response->getbody(); //... 51

<?php namespace Acme\FeedBundle\Service\FeedAggregator Dependencies use Guzzle\Http\ClientInterface; use Acme\Logger\LoggerInterface; class FeedAggregator { private $client; Class private $logger; on only depends interfaces are pushed. Implementations are injected at runtime public function construct(clientinterface $client, LoggerInterface $logger) { $this->client = $client; $this->logger = $logger; Easy to replace, even dynamically (for testing) public function retrievefeed ($baseurl, $path) { $request = $this->client->setbaseurl($baseurl)->get($path); $response = $request->send(); if (200!= $response->getstatuscode()) On the level of the class, { $this->logger->log('could not get: '.$baseurl.$path); You are now experts for return null; Dependency Injection. return $response->getbody(); //... Any questions? 52

<?php namespace Acme\FeedBundle\Service\FeedAggregator Dependencies use Guzzle\Http\ClientInterface; use Acme\Logger\LoggerInterface; class FeedAggregator { private $client; Class private $logger; on only depends interfaces are pushed. Implementations are injected at runtime public function construct(clientinterface $client, LoggerInterface $logger) { $this->client = $client; $this->logger = $logger; Easy to replace, even dynamically (for testing) public function retrievefeed ($baseurl, $path) { $request = $this->client->setbaseurl($baseurl)->get($path); $response = $request->send(); if (200!= $response->getstatuscode()) On the level of the class, { $this->logger->log('could not get: '.$baseurl.$path); You are now experts for return null; Dependency Injection. return $response->getbody(); //... Who constructs and pushes all the dependencies? 53

54

Dependency Injection Container DI Container, DIC, Service Container, the Container DIC 55

56

Very Many Frameworks support Dependency Injection 57

DI is very easy in Symfony 2 58

DI is very easy in Symfony 2 Any ordinary PHP class can be managed by DIC Only 2 lines of configuration per class are needed Any class managed by the DIC is called a Service 59

DI is very easy in Symfony 2 Any ordinary PHP class can be managed by DIC Only 2 lines of configuration per class are needed Any class managed by the DIC is called a Service # app/config/config.yml #... services: my_service: class: Acme\MyBundle\Service\AwesomeClass 60

DI is very easy in Symfony 2 Any ordinary PHP class can be managed by DIC Only 2 lines of configuration per class are needed Any class managed by the DIC is called a Service # app/config/config.yml Class to manage #... services: my_service: class: Acme\MyBundle\Service\AwesomeClass Name of the new service 61

# php app/console container:debug 62

DI is very easy in Symfony 2 Any ordinary PHP class can be managed by DIC Only 2 lines of configuration per class are needed Any class managed by the DIC is called a Service # app/config/config.yml #... services: my_service: class: Acme\MyBundle\Service\AwesomeClass 63

DI is very easy in Symfony 2 Any ordinary PHP class can be managed by DIC Only 2 lines of configuration per class are needed Any class managed by the DIC is called a Service # app/config/config.yml #... services: my_service: class: Acme\MyBundle\Service\AwesomeClass arguments: some_arg: string another: - array_member - array_member even_more: @another_service 64

DI is very easy in Symfony 2 Any ordinary PHP class can be managed by DIC Only 2 lines of configuration per class are needed Any class managed by the DIC is called a Service # app/config/config.yml Arguments can be #... strings, numbers, services: my_service: arrays, placeholders, class: Acme\MyBundle\Service\AwesomeClass and many more... arguments: some_arg: string another: Any other service - array_member can be injected as - array_member even_more: @another_service as argument 65

<?php use Guzzle\Http\ClientInterface; use Acme\Logger\LoggerInterface; class FeedAggregator { private $client; private $logger; public function construct(clientinterface $client, LoggerInterface $logger) { $this->client = $client; $this->logger = $logger; public function retrievefeed ($baseurl, $path) { $request = $this->client->setbaseurl($baseurl)->get($path); $response = $request->send(); if (200!= $response->getstatuscode()) { $this->logger->log('could not get: '.$host.$path); return null; return $response->getbody(); //... 66

<?php use Guzzle\Http\ClientInterface; use Acme\Logger\LoggerInterface; class FeedAggregator { private $client; private $logger; public function construct(clientinterface $client, LoggerInterface $logger) { $this->client = $client; $this->logger = $logger; public function retrievefeed ($baseurl, $path) { $request = $this->client->setbaseurl($baseurl)->get($path); $response = $request->send(); 67 if (200!= $response->getstatuscode()) {

# app/config/config.yml #... services: feed_aggregator: class: Acme\FeedBundle\Service\FeedAggregator arguments: client: @http_client logger: @logger <?php use Guzzle\Http\ClientInterface; use Acme\Logger\LoggerInterface; class FeedAggregator { private $client; private $logger; public function construct(clientinterface $client, LoggerInterface $logger) { $this->client = $client; $this->logger = $logger; public function retrievefeed ($baseurl, $path) { $request = $this->client->setbaseurl($baseurl)->get($path); $response = $request->send(); 68 if (200!= $response->getstatuscode()) {

# app/config/config.yml #... services: feed_aggregator: class: Acme\FeedBundle\Service\FeedAggregator arguments: client: @http_client logger: @logger <?php use Guzzle\Http\ClientInterface; use Acme\Logger\LoggerInterface; class FeedAggregator { private $client; private $logger; public function construct(clientinterface $client, LoggerInterface $logger) { $this->client = $client; $this->logger = $logger; public function retrievefeed ($baseurl, $path) { $request = $this->client->setbaseurl($baseurl)->get($path); $response = $request->send(); 69 if (200!= $response->getstatuscode()) {

Different Config needed for Functional Testing? app/config/config.yml app/config/config_dev.yml app/config/config_test.yml 70 Put it here here

71

wiederverwendbar unit-testbar Großteil der Codebasis 72

nicht wiederverwendbar nicht unit-testbar Minimum an Code wiederverwendbar unit-testbar Großteil der Codebasis 73

Dependency Injection 74

Dependency Injection Services 75

Controller bekommen Instanzen der Services vom DIC, z.b. so: $this->get( logger ) Services 76

Nachhaltige Architektur für große Web-Projekte Modularität Erweiterbarkeit Wartbarkeit Testbarkeit Performance 77

Further Reading http://fabien.potencier.org/article/11/what-is-dependency-injection http://symfony.com/doc/current/components/dependency_injection/compilation.html http://symfony.com/doc/current/cookbook/service_container/compiler_passes.html Use the source... 78

79

Commonly used Types of Events Kernel events Form events Doctrine events 80

Kernel Events 81

Kernel Events Used in SensioFrameworkExtraBundle to act on the @Template annotation. 82

To act on a Kernel Event Create a Listener Class Let the DIC do all remaining work for you 83

To act on a Kernel Event Create a Listener Class Let the DIC do all remaining work for you Create a service definition 84

To act on a Kernel Event # app/config/config.yml services: your_listener_name: class: Acme\DemoBundle\EventListener\AcmeExceptionListener Create a Listener Class Let the DIC do all remaining work for you Create a service definition 85

To act on a Kernel Event # app/config/config.yml services: your_listener_name: class: Acme\DemoBundle\EventListener\AcmeExceptionListener Create a Listener Class Let the DIC do all remaining work for you Create a service definition Add a tag labeling the service as a listener 86

To act on a Kernel Event # app/config/config.yml services: your_listener_name: class: Acme\DemoBundle\EventListener\AcmeExceptionListener tags: - { name: kernel.event_listener, event: kernel.exception, method: onkernelexception Create a Listener Class Let the DIC do all remaining work for you Create a service definition Add a tag labeling the service as a listener 87

How to listen to Kernel events listener class + service tag Form events Doctrine events 88

How to listen to Kernel events listener class + service tag Form events listener class + service tag closure inside form type class Doctrine events 89

How to listen to Kernel events listener class + service tag Form events listener class + service tag closure inside form type class Doctrine events listener class + service tag callback method inside entity class 90

Time Checkpoint Skip? 91

Which listeners are active? Your answer? 92

Which listeners are active? Kernel events listener class + service tag Form events listener class + service tag closure inside form type class Doctrine events listener class + service tag callback method inside entity class Your own custom events listener class + service tag closure etc. 93

Which listeners are active? Symfony profiler > Events 94

Which listeners are active? Symfony profiler > Events 95

Which listeners are active? Symfony profiler > Events 96

Which listeners are active? Symfony profiler > Events Check in your own Command oder Controller 97

Which listeners are active? Symfony profiler > Events Check in your own Command oder Controller $listeners = $this->getcontainer()->get('event_dispatcher')->getlisteners(); 98

Which listeners are active? Symfony profiler > Events Check in your own Command oder Controller $listeners = $this->getcontainer()->get('event_dispatcher')->getlisteners(); print_r (array_keys($listeners)); print_r (array_keys($listeners['kernel.view'])); 99

Which listeners are active? Symfony profiler > Events Check in your own Command oder Controller $listeners = $this->getcontainer()->get('event_dispatcher')->getlisteners(); print_r (array_keys($listeners)); print_r (array_keys($listeners['kernel.view'])); $entitymanager = $this->getcontainer()->get('doctrine.orm.entity_manager'); Doctrine Entity Manager uses an instance of the Doctrine Event Manager (injected by the DIC). 100

Which listeners are active? Symfony profiler > Events Check in your own Command oder Controller $listeners = $this->getcontainer()->get('event_dispatcher')->getlisteners(); print_r (array_keys($listeners)); print_r (array_keys($listeners['kernel.view'])); $entitymanager = $this->getcontainer()->get('doctrine.orm.entity_manager'); $listeners = $entitymanager->geteventmanager()->getlisteners(); print_r (array_keys($listeners)); //... 101

Which listeners are active? Symfony profiler > Events Check in your own Command oder Controller ListenersDebugCommandBundle 102

ListenersDebugCommandBundle https://github.com/egulias/listenersdebugcommandbundle app/console container:debug:listeners --event=event.name: if issued will filter to show only the listeners listening to the given name (ordered by descending priority, unless you use: --order-asc) --show-private : if issued will show also private services... 103

Nachhaltige Architektur für große Web-Projekte Modularität Erweiterbarkeit Wartbarkeit Testbarkeit Performance 104

Gute Performance machbar? Deal Finder Bundle Deal Lookup Bundle Product Search Bundle Shop Crawler Bundle Shop Aggregator Bundle Product Bundle DIC Tag: shop_service Sol-r Bundle Client Lib. Sol-r Sol-r Server Elastic Search Bundle Client Lib. Elastic S. Elastic S. Server Doctrine Bundle Datenbank Guzzle Bundle Guzzle HTTP Client Generischer Webserver 105 ShopAAA Bundle ShopBBB Bundle ShopCCC Bundle

Gute Performance machbar! Deal Finder Bundle Danke Opcache: Byte-Code im Deal Lookup Bundle RAM Product Search Bundle Shop Crawler Bundle Shop Aggregator Bundle Product Bundle DIC Tag: shop_service Sol-r Bundle Client Lib. Sol-r Sol-r Server Elastic Search Bundle Client Lib. Elastic S. Elastic S. Server Doctrine Bundle Datenbank Guzzle Bundle Guzzle HTTP Client Generischer Webserver 106 ShopAAA Bundle ShopBBB Bundle ShopCCC Bundle

Nachhaltige Architektur für große Web-Projekte Modularität Erweiterbarkeit Wartbarkeit Testbarkeit Performance 107

Further Reading: Dependency Injection http://fabien.potencier.org/article/11/what-is-dependency-injection http://symfony.com/doc/current/components/dependency_injection/compilation.html http://symfony.com/doc/current/cookbook/service_container/compiler_passes.html Use the source... 108

Further Reading: Event Dispatcher Symfony Event Dispatcher http://symfony.com/doc/current/components/event_dispatcher/ http://symfony.com/doc/current/cookbook/event_dispatcher/ http://symfony.com/doc/current/cookbook/doctrine/event_listeners_subscribers.html http://api.symfony.com/2.4/symfony/component/eventdispatcher/eventdispatcher.html Doctrine Event Manager http://docs.doctrine-project.org/projects/doctrine1/en/latest/en/manual/event-listeners.html http://www.whitewashing.de/2013/07/24/doctrine_and_domainevents.html http://www.doctrine-project.org/api/orm/2.4/class-doctrine.orm.entitymanager.html http://www.doctrine-project.org/api/common/2.4/class-doctrine.common.eventmanager.h 109

Vielen Dank für Eure Aufmerksamkeit! 110

Fragen? Ideen, Wünsche, Anmerkungen? 111