symfony2 meets drupal
TRANSCRIPT
-
7/31/2019 Symfony2 Meets Drupal
1/131
meets
http://www.flickr.com/photos/nimport_nawak/3404931191
http://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://www.flickr.com/photos/nimport_nawak/3404931191http://www.flickr.com/photos/nimport_nawak/3404931191http://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svghttp://localhost/Users/fabien/Downloads/symfony_black_02.svg -
7/31/2019 Symfony2 Meets Drupal
2/131
Drupal 8 meets Symfony
Fabien Potencier@fabpot
Founder of
Lead developer of Open-Source librariesTwig, Swiftmailer, Silex, Pirum, Sismo, Pimple, Goutte, ...
Symfony founder and lead developer
mailto:[email protected]:[email protected]:[email protected] -
7/31/2019 Symfony2 Meets Drupal
3/131
Drupal 8 meets Symfony
Lukas Kahwe Smith@lsmith
Works for in Switzerland
PHP 5.3 Release Manager
Co-lead of PHPCRSymfony2 core contributor
mailto:[email protected]:[email protected]:[email protected] -
7/31/2019 Symfony2 Meets Drupal
4/131
http://www.flickr.com/photos/dunechaser/160405823
Drupal 8 meets Symfony
How many of you are
PHP developers?
http://www.flickr.com/photos/davemorris/3431970729http://www.flickr.com/photos/davemorris/3431970729 -
7/31/2019 Symfony2 Meets Drupal
5/131
Drupal 8 meets Symfony
http://www.flickr.com/photos/dunechaser/142079357
How many of you are
Symfony aware?
http://www.flickr.com/photos/davemorris/3431970729http://www.flickr.com/photos/davemorris/3431970729 -
7/31/2019 Symfony2 Meets Drupal
6/131
Drupal 8 meets Symfony
We are both outsiders
We are both quite experiencedPHP developers
We have a rough understandingof the hook paradigm aka the Drupal way
http://www.flickr.com/photos/pictureperfectpose/76138988
http://www.flickr.com/photos/pictureperfectpose/76138988http://www.flickr.com/photos/pictureperfectpose/76138988 -
7/31/2019 Symfony2 Meets Drupal
7/131Drupal 8 meets Symfony
A sad realization
It would take a long time for usto be productive in Drupallet alone work on the core
And everything we learn along the waywould only help us with Drupal
-
7/31/2019 Symfony2 Meets Drupal
8/131Drupal 8 meets Symfony
What others do
Building on top of long establishedOO design patterns
Leverage new PHP language features
and performance improvementsShare code!
-
7/31/2019 Symfony2 Meets Drupal
9/131
Drupal 8 meets Symfony
So Drupal is wrong?
No, the question is justif the benefits of doing things differently
outweigh the disadvantages
-
7/31/2019 Symfony2 Meets Drupal
10/131
Drupal 8 meets Symfony
Core brain drain
The complexity of the custom code thats used
and the non-standard architecturecombines to create a barrier to entry
for developers new to Drupal(both experienced and novice developers alike).
buytaert.net
http://buytaert.net/the-future-is-a-restful-drupalhttp://buytaert.net/the-future-is-a-restful-drupalhttp://buytaert.net/the-future-is-a-restful-drupal -
7/31/2019 Symfony2 Meets Drupal
11/131
Drupal 8 meets Symfony
What could be gained
Facilitate the refactoringtowards a framework core
Focus Drupal dev resources on the CMS
Easier integration with other applications
Ensure that the Drupal developer poolcontinues to grow
-
7/31/2019 Symfony2 Meets Drupal
12/131
Drupal 8 meets Symfony
A decision was made
While these changes may seem large, and some of them are,
we believe that they will achieve the right balancebetween empowering Drupal's design and architecture,and moving toward more modern, standard,
well-tested code and techniques
to empower a new generation of developers.
buytaert.net
http://buytaert.net/the-future-is-a-restful-drupalhttp://buytaert.net/the-future-is-a-restful-drupalhttp://buytaert.net/the-future-is-a-restful-drupal -
7/31/2019 Symfony2 Meets Drupal
13/131
Drupal 8 meets Symfony
How to collaborate?
Symfony2 is MIT licensedwhich is GPL compatible
Symfony2 development isvery transparently managed on github.com
We want to ensure Symfony2works for Drupal, phpBB, etc.
https://github.com/symfony/symfony/pullshttps://github.com/symfony/symfony/pullshttps://github.com/symfony/symfony/pulls -
7/31/2019 Symfony2 Meets Drupal
14/131
Drupal 8 meets Symfony
For example ...
Symfony2.0 provides a conceptcalled flash messages to pass messages
to the very next request
drupal_set_message() could be replacedby this if we make it a bit more flexible
Drak, lead of the Zikula CMS, created a PRto address exactly these concerns
https://github.com/symfony/symfony/pull/3267https://github.com/symfony/symfony/pull/3267https://github.com/symfony/symfony/pull/3267 -
7/31/2019 Symfony2 Meets Drupal
15/131
Drupal 8 meets Symfony
What isSymfony?
http://www.flickr.com/photos/apranihita/141159146/
http://www.flickr.com/photos/apranihita/141159146/http://www.flickr.com/photos/apranihita/141159146/ -
7/31/2019 Symfony2 Meets Drupal
16/131
Drupal 8 meets Symfony
http://www.flickr.com/photos/bigpinkcookie/22716359
http://www.flickr.com/photos/bigpinkcookie/22716359http://www.flickr.com/photos/bigpinkcookie/22716359 -
7/31/2019 Symfony2 Meets Drupal
17/131
Drupal 8 meets Symfony
is...
... a reusable set ofstandalone, decoupled, and cohesivePHP components that solve
common web development problems
http://www.flickr.com/photos/krislitman/493626935
http://www.flickr.com/photos/krislitman/493626935http://www.flickr.com/photos/krislitman/493626935 -
7/31/2019 Symfony2 Meets Drupal
18/131
Drupal 8 meets Symfony
is...
... an Object-Oriented set of classes
... compatible with PHP 5.3 and later
http://www.flickr.com/photos/krislitman/493626935
http://www.flickr.com/photos/krislitman/493626935http://www.flickr.com/photos/krislitman/493626935 -
7/31/2019 Symfony2 Meets Drupal
19/131
Drupal 8 meets Symfony
DependencyInjectionEventDispatcher
HttpFoundation
DomCrawler
ClassLoader
CssSelector
HttpKernel
BrowserKitTemplating
Translation
Filesystem
Serializer
ValidatorSecurity
Routing
ConsoleProcessConfig
Finder
Locale
Yaml
Form
-
7/31/2019 Symfony2 Meets Drupal
20/131
Drupal 8 meets Symfony
is...
... a full-stack web framework
http://www.flickr.com/photos/krislitman/493626935
http://www.flickr.com/photos/krislitman/493626935http://www.flickr.com/photos/krislitman/493626935 -
7/31/2019 Symfony2 Meets Drupal
21/131
Drupal 8 meets Symfony
Official websitehttp://symfony.com/
Official repositoryhttps://github.com/symfony/symfony
http://www.flickr.com/photos/28634332@N05/5654415647
http://www.flickr.com/photos/28634332@N05/5654415647http://www.flickr.com/photos/28634332@N05/5654415647https://github.com/symfony/symfonyhttps://github.com/symfony/symfony -
7/31/2019 Symfony2 Meets Drupal
22/131
Drupal 8 meets Symfony
Official websitehttp://symfony.com/components
Official repositorieshttps://github.com/symfony/XXXX
Components
http://www.flickr.com/photos/28634332@N05/5654415647
http://www.flickr.com/photos/28634332@N05/5654415647http://www.flickr.com/photos/28634332@N05/5654415647https://github.com/symfony/symfonyhttps://github.com/symfony/symfonyhttp://symfony.com/componentshttp://symfony.com/components -
7/31/2019 Symfony2 Meets Drupal
23/131
Drupal 8 meets Symfony
Mailing-listhttps://groups.google.com/group/symfony2
IRC channelirc://irc.freenode.net/symfony
http://www.flickr.com/photos/28634332@N05/5654415647
http://www.flickr.com/photos/28634332@N05/5654415647http://www.flickr.com/photos/28634332@N05/5654415647 -
7/31/2019 Symfony2 Meets Drupal
24/131
Drupal 8 meets Symfony
Which Open-Source projects
are already using theSymfony Components?
http://www.flickr.com/photos/maistora/3014414972
http://www.flickr.com/photos/maistora/3014414972http://www.flickr.com/photos/maistora/3014414972 -
7/31/2019 Symfony2 Meets Drupal
25/131
Drupal 8 meets Symfony
Behat - a BDD frameworkConsole, DependencyInjection, EventDispatcher, Finder, Yaml, Config, Translation
Doctrine - an object relational mapper
Console, Yaml
Propel - an object relational mapperConsole, ClassLoader, Yaml
PHPUnit - a PHP unit testing frameworkYaml, (Finder soon?)
Jackalope - a content repository (JCR 170/283)ClassLoader, Console
Developer Tools
http://www.flickr.com/photos/c_r_i_s/77763712
http://www.flickr.com/photos/c_r_i_s/77763712http://www.flickr.com/photos/c_r_i_s/77763712 -
7/31/2019 Symfony2 Meets Drupal
26/131
Drupal 8 meets Symfony
Silex - a micro-frameworkBrowerKit, CssSelector, DomCrawler, EventDispatcher,
HttpFoundation, HttpKernel, Routing, Form, Translation, Validator
PPI 2 - a frameworkClassLoader, HttpFoundation, Routing, Templating
Frameworks
http://www.flickr.com/photos/c_r_i_s/77763712
P d
http://www.flickr.com/photos/c_r_i_s/77763712http://www.flickr.com/photos/c_r_i_s/77763712 -
7/31/2019 Symfony2 Meets Drupal
27/131
Drupal 8 meets Symfony
easybook - a book publishing platformClassLoader, Console, EventDispatcher, Filesystem, Finder, Yaml
Midgard CMS - a content management frameworkuses the full-stack framework
Zikula - ex PostNuke - an application frameworkHttpFoundation, HttpKernel, EventDispatcher,
ClassLoader, DependencyInjection
phpBB - a bulletin board softwareEventDispatcher, and most of them for version 4?
Products
http://www.flickr.com/photos/c_r_i_s/77763712
http://www.flickr.com/photos/c_r_i_s/77763712http://www.flickr.com/photos/c_r_i_s/77763712 -
7/31/2019 Symfony2 Meets Drupal
28/131
Drupal 8 meets Symfony
What aboutDrupal 8?
http://www.flickr.com/photos/aloshbennett/619307160
http://www.flickr.com/photos/aloshbennett/619307160http://www.flickr.com/photos/aloshbennett/619307160http://www.flickr.com/photos/aloshbennett/619307160 -
7/31/2019 Symfony2 Meets Drupal
29/131
Drupal 8 meets Symfony
DependencyInjectionEventDispatcher
HttpFoundation
DomCrawler
ClassLoader
CssSelector
HttpKernel
BrowserKitTemplating
Translation
Filesystem
Serializer
ValidatorSecurity
Routing
ConsoleProcessConfig
Finder
Locale
Yaml
Form
-
7/31/2019 Symfony2 Meets Drupal
30/131
Drupal 8 meets Symfony
DependencyInjectionEventDispatcher
HttpFoundation
DomCrawler
ClassLoader
CssSelector
HttpKernel
BrowserKitTemplating
Translation
Filesystem
Serializer
ValidatorSecurity
Routing
ConsoleProcessConfig
Finder
Locale
Yaml
Form
-
7/31/2019 Symfony2 Meets Drupal
31/131
Drupal 8 meets Symfony
Using the
SymfonyComponents
http://www.flickr.com/photos/35168673@N03/6086229920
Git
http://www.flickr.com/photos/35168673@N03/6086229920http://www.flickr.com/photos/35168673@N03/6086229920 -
7/31/2019 Symfony2 Meets Drupal
32/131
Drupal 8 meets Symfony
$ git clone https://github.com/symfony/Console.git
$ git co v2.0.9
$ git co 2.0
$ git co master
Git
A hi
https://github.com/symfony/Console.githttps://github.com/symfony/Console.git -
7/31/2019 Symfony2 Meets Drupal
33/131
Drupal 8 meets Symfony
$ curl -O https://github.com/symfony/Console/zipball/v2.0.9
$ curl -O https://github.com/symfony/Console/zipball/2.0
$ curl -O https://github.com/symfony/Console/zipball/master
Archives
PEAR
https://github.com/symfony/Console.githttps://github.com/symfony/Console.githttps://github.com/symfony/Console.githttps://github.com/symfony/Console.githttps://github.com/symfony/Console.githttps://github.com/symfony/Console.git -
7/31/2019 Symfony2 Meets Drupal
34/131
Drupal 8 meets Symfony
$ pear channel-discover pear.symfony.com
$ pear install symfony2/Console-2.0.9
PEAR
C
-
7/31/2019 Symfony2 Meets Drupal
35/131
Drupal 8 meets Symfony
composer.json
{"require": {
"symfony/console": "2.1.*",
"symfony/http-foundation": "v2.0.9"
}
}
curl -s http://getcomposer.org/installer | php
php composer.phar install
Composer
http://getcomposer.org/installerhttp://getcomposer.org/installerhttp://getcomposer.org/installer -
7/31/2019 Symfony2 Meets Drupal
36/131
Drupal 8 meets Symfony
Symfony Componentscomes with Drupal 8
-
7/31/2019 Symfony2 Meets Drupal
37/131
Drupal 8 meets Symfony
ClassLoader
-
7/31/2019 Symfony2 Meets Drupal
38/131
Drupal 8 meets Symfony
http://symfony.com/PSR0
http://symfony.com/PSR0http://symfony.com/PSR0http://symfony.com/PSR0 -
7/31/2019 Symfony2 Meets Drupal
39/131
Drupal 8 meets Symfony
require_once__DIR__.'/src/Symfony/Component/ClassLoader/UniversalClassLoader.php';
use Symfony\Component\ClassLoader\UniversalClassLoader;
$loader=newUniversalClassLoader();$loader->registerNamespaces(array( 'Symfony'=>__DIR__.'/vendor/symfony/src',));
$loader->register();
-
7/31/2019 Symfony2 Meets Drupal
40/131
$loader->registerPrefixes(array(
'Twig_'=>__DIR__.'/vendor/twig/lib',));
Drupal 8 meets Symfony
-
7/31/2019 Symfony2 Meets Drupal
41/131
Drupal 8 meets Symfony
The Symfony ClassLoader Componentloads your project classes automatically
if they follow some standard conventions
http://www.flickr.com/photos/ynaffitx/4667769355
http://www.flickr.com/photos/ynaffitx/4667769355http://www.flickr.com/photos/ynaffitx/4667769355 -
7/31/2019 Symfony2 Meets Drupal
42/131
Drupal 8 meets Symfony
HttpFoundation
-
7/31/2019 Symfony2 Meets Drupal
43/131
Drupal 8 meets Symfony
http://www.flickr.com/photos/deniscollette/6741424757
HTTPHTTP/1.1RFC 2616
http://www.ietf.org/rfc/rfc2616.txt
http://tools.ietf.org/wg/httpbis/
http://www.flickr.com/photos/deniscollette/6741424757http://tools.ietf.org/wg/httpbis/http://tools.ietf.org/wg/httpbis/http://www.ietf.org/rfc/rfc2616.txthttp://www.ietf.org/rfc/rfc2616.txthttp://www.flickr.com/photos/deniscollette/6741424757http://www.flickr.com/photos/deniscollette/6741424757 -
7/31/2019 Symfony2 Meets Drupal
44/131
Drupal 8 meets Symfony
The Web in action
The User asks for a Resource in a Browser
http://example.com/foo.html
http://example.com/foo.htmlhttp://example.com/foo.htmlhttp://example.com/foo.htmlhttp://example.com/foo.htmlhttp://example.com/foo.htmlhttp://example.com/foo.html -
7/31/2019 Symfony2 Meets Drupal
45/131
Drupal 8 meets Symfony
The Web in action
The User asks for a Resource in a Browser
The Browser sends a Request to the Server
GET /foo.html HTTP/1.1Host: example.com
-
7/31/2019 Symfony2 Meets Drupal
46/131
Drupal 8 meets Symfony
The Web in action
The User asks for a Resource in a Browser
The Browser sends a Request to the Server
The Server sends back a Response to the Browser
HTTP/1.1 200 OKDate: Wed, 15 Oct 2005 07:07:07 GMT
Content-Length: 14Content-Type: text/html
Hello World!
-
7/31/2019 Symfony2 Meets Drupal
47/131
Drupal 8 meets Symfony
The Web in action
The User asks for a Resource in a Browser
The Browser sends a Request to the Server
The Server sends back a Response to the BrowserThe Browser displays the Resource to the User
-
7/31/2019 Symfony2 Meets Drupal
48/131
Drupal 8 meets Symfony
The Client sendsa Request to the Server
The Server sends backa Response to the Client
Request
GET /foo.html HTTP/1.1Host: example.com
Response
HTTP/1.1 200 OKDate: Wed, 15 Oct 2005 07:07:07 GMTContent-Length: 14Content-Type: text/html
Hello World!
-
7/31/2019 Symfony2 Meets Drupal
49/131
Drupal 8 meets Symfony
Request
GET /foo.html HTTP/1.1
Host: example.com
http://www.flickr.com/photos/splorp/64027565
Request
http://www.flickr.com/photos/splorp/64027565http://www.flickr.com/photos/splorp/64027565 -
7/31/2019 Symfony2 Meets Drupal
50/131
session_start();
$name=$_GET['name'];// $_POST, $_FILE, $_COOKIE, ...
echo $_SESSION['name'];
$method=$_SERVER['REQUEST_METHOD'];
Drupal 8 meets Symfony
Request
GET /foo.html HTTP/1.1Host: example.com
Request
-
7/31/2019 Symfony2 Meets Drupal
51/131
Drupal 8 meets Symfony
$clientIp=$_SERVER['REMOTE_ADDR'];
Request
GET /foo.html HTTP/1.1Host: example.com
Request
-
7/31/2019 Symfony2 Meets Drupal
52/131
Drupal 8 meets Symfony
if (isset($_SERVER['HTTP_CLIENT_IP'])) {return$_SERVER['HTTP_CLIENT_IP'];
}
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ips=explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'], 2);
returnisset($ips[0]) ? trim($ips[0]) : '';}
return$_SERVER['REMOTE_ADDR'];
Request
GET /foo.html HTTP/1.1Host: example.com
Request
-
7/31/2019 Symfony2 Meets Drupal
53/131
Drupal 8 meets Symfony
if ($trustProxy) {if (isset($_SERVER['HTTP_CLIENT_IP'])) {
return$_SERVER['HTTP_CLIENT_IP'];}
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ips=explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'], 2);
returnisset($ips[0]) ? trim($ips[0]) : '';}
}
return$_SERVER['REMOTE_ADDR'];
Request
GET /foo.html HTTP/1.1Host: example.com
Request
-
7/31/2019 Symfony2 Meets Drupal
54/131
Drupal 8 meets Symfony
http://www.flickr.com/photos/viamoi/3338093351
Not Object-Oriented
Low-level abstraction only
Singleton like
Not Object-Oriented
Request
GET /foo.html HTTP/1.1Host: example.com
Request
http://www.flickr.com/photos/viamoi/3338093351http://www.flickr.com/photos/viamoi/3338093351 -
7/31/2019 Symfony2 Meets Drupal
55/131
Drupal 8 meets Symfony
use Symfony\Component\HttpFoundation\Request;
$request=Request::createFromGlobals();
$request=Request::create('/hello.html', 'GET');
$request->overrideGlobals();
Request
GET /foo.html HTTP/1.1Host: example.com
Request
-
7/31/2019 Symfony2 Meets Drupal
56/131
Drupal 8 meets Symfony
$request->query->get('name', 'Default');
$request->getSession()->get('name');
$request->getPathInfo();
$request->getClientIp();
Request::trustProxyData();
Request
GET /foo.html HTTP/1.1Host: example.com
Response
-
7/31/2019 Symfony2 Meets Drupal
57/131
Drupal 8 meets Symfony
Response
HTTP/1.1 200 OKDate: Wed, 15 Oct 2005 07:07:07 GMTContent-Length: 14Content-Type: text/html
Hello World!
http://www.flickr.com/photos/splorp/64027565
Response
http://www.flickr.com/photos/splorp/64027565http://www.flickr.com/photos/splorp/64027565 -
7/31/2019 Symfony2 Meets Drupal
58/131
Drupal 8 meets Symfony
p
HTTP/1.1 200 OKDate: Wed, 15 Oct 2005 07:07:07 GMTContent-Length: 14Content-Type: text/html
Hello World!
header('HTTP/1.0 404 Not Found');
header('Content-Type: text/html; charset=UTF-8');
setcookie('name', $name);
$_SESSION['name'] ='Fabien';echo'Hello '.$name;
Response
-
7/31/2019 Symfony2 Meets Drupal
59/131
Drupal 8 meets Symfony
http://www.flickr.com/photos/viamoi/3338093351
Low-level abstraction only
Singleton like
Does not play well with the CLI
Not Object-Oriented
p
HTTP/1.1 200 OKDate: Wed, 15 Oct 2005 07:07:07 GMTContent-Length: 14Content-Type: text/html
Hello World!
Response
http://www.flickr.com/photos/viamoi/3338093351http://www.flickr.com/photos/viamoi/3338093351 -
7/31/2019 Symfony2 Meets Drupal
60/131
Drupal 8 meets Symfony
use Symfony\Component\HttpFoundation\Response;
$response=newResponse('Not Found', 404, array('Content-Type'=>'text/plain'));$response=newResponse();
$response->setContent('Hello World');
$response->send();
p
HTTP/1.1 200 OKDate: Wed, 15 Oct 2005 07:07:07 GMTContent-Length: 14Content-Type: text/html
Hello World!
Response
-
7/31/2019 Symfony2 Meets Drupal
61/131
Drupal 8 meets Symfony
use Symfony\Component\HttpFoundation\StreamedResponse;
$response=newStreamedResponse(function () { echo'foo'; flush();
echo'bar';});$response->send();
p
HTTP/1.1 200 OKDate: Wed, 15 Oct 2005 07:07:07 GMTContent-Length: 14Content-Type: text/html
Hello World!
Response
-
7/31/2019 Symfony2 Meets Drupal
62/131
Drupal 8 meets Symfony
$headers=$response->headers;
$headers->set( 'Content-Disposition', $headers->makeDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'foo.pdf'));
p
HTTP/1.1 200 OKDate: Wed, 15 Oct 2005 07:07:07 GMTContent-Length: 14Content-Type: text/html
Hello World!
Response
-
7/31/2019 Symfony2 Meets Drupal
63/131
Drupal 8 meets Symfony
$response->prepare($request);
p
HTTP/1.1 200 OKDate: Wed, 15 Oct 2005 07:07:07 GMTContent-Length: 14Content-Type: text/html
Hello World!
-
7/31/2019 Symfony2 Meets Drupal
64/131
Drupal 8 meets Symfony
SessionManagement
http://www.flickr.com/photos/tomvu/5371659662
http://www.flickr.com/photos/tomvu/5371659662http://www.flickr.com/photos/tomvu/5371659662 -
7/31/2019 Symfony2 Meets Drupal
65/131
Drupal 8 meets Symfony
The Symfony HttpFoundation Componentdefines a feature-full object-oriented layer
for the HTTP messages
http://www.flickr.com/photos/ynaffitx/4667769355
http://www.flickr.com/photos/ynaffitx/4667769355http://www.flickr.com/photos/ynaffitx/4667769355 -
7/31/2019 Symfony2 Meets Drupal
66/131
Drupal 8 meets Symfony
It replaces PHP native global variables and functionsto allow writing better, more secure, and more testable code
http://www.flickr.com/photos/ynaffitx/4667769355
http://www.flickr.com/photos/ynaffitx/4667769355http://www.flickr.com/photos/ynaffitx/4667769355 -
7/31/2019 Symfony2 Meets Drupal
67/131
Drupal 8 meets Symfony
Routing
-
7/31/2019 Symfony2 Meets Drupal
68/131
Drupal 8 meets Symfony
use Symfony\Component\Routing\Route;
$route=newRoute('/node/{id}', array( '_controller'=>'SomeClass::someMethod'));
use Symfony\Component\Routing\RouteCollection;
$routes=newRouteCollection();
$routes->add('node', $route);
f \ \ i \
-
7/31/2019 Symfony2 Meets Drupal
69/131
Drupal 8 meets Symfony
use Symfony\Component\Routing\RequestContext;use Symfony\Component\Routing\Matcher\UrlMatcher;
$matcher=newUrlMatcher($routes, newRequestContext());
$attributes=$matcher->match('/node/12');$attributes=$matcher->match($request->getPathInfo());
print_r($attributes);
array( '_route' =>'node',
'id' =>12, '_controller'=>'SomeClass::someMethod',);
-
7/31/2019 Symfony2 Meets Drupal
70/131
Drupal 8 meets Symfony
use Symfony\Component\Routing\Generator\UrlGenerator;
$generator=newUrlGenerator($routes, $context);
echo$generator->generate('node', array('id'=>12));
-
7/31/2019 Symfony2 Meets Drupal
71/131
Drupal 8 meets Symfony
The Symfony Routing Componentdecouples the look of URLs
from the code that handle them
http://www.flickr.com/photos/ynaffitx/4667769355
http://www.flickr.com/photos/ynaffitx/4667769355http://www.flickr.com/photos/ynaffitx/4667769355 -
7/31/2019 Symfony2 Meets Drupal
72/131
Drupal 8 meets Symfony
EventDispatcher
-
7/31/2019 Symfony2 Meets Drupal
73/131
Drupal 8 meets Symfony
use Symfony\Component\EventDispatcher\EventDispatcher;
$dispatcher=newEventDispatcher();
$callable=function (Event$event) { // do something
};$dispatcher->addListener('event_name', $callable);
$dispatcher->dispatch('event_name', newEvent());
-
7/31/2019 Symfony2 Meets Drupal
74/131
Drupal 8 meets Symfony
The Symfony EventDispatcher Componentimplements a lightweight version
of the Observer design pattern
http://www.flickr.com/photos/ynaffitx/4667769355
http://www.flickr.com/photos/ynaffitx/4667769355http://www.flickr.com/photos/ynaffitx/4667769355 -
7/31/2019 Symfony2 Meets Drupal
75/131
Drupal 8 meets Symfony
HttpKernel
-
7/31/2019 Symfony2 Meets Drupal
76/131
Drupal 8 meets Symfony
Request Response
HTTP/1.1 200 OKDate: Wed, 15 Oct 2005 07:07:07 GMTContent-Length: 14Content-Type: text/html
Hello World!
GET /foo.html HTTP/1.1Host: example.com
http://www.flickr.com/photos/-bast-/349497988
The web in action
http://www.flickr.com/photos/-bast-/349497988http://www.flickr.com/photos/-bast-/349497988http://www.flickr.com/photos/-bast-/349497988 -
7/31/2019 Symfony2 Meets Drupal
77/131
Drupal 8 meets Symfony
The web in action
The User asks for a Resource in a BrowserThe Browser sends a Request to the Server
Symfony gives the Developer a Request Object
The Developerconverts the Request Object to a Response Object
The Server sends back a Response to the Browser
The Browser displays the Resource to the User
-
7/31/2019 Symfony2 Meets Drupal
78/131
Drupal 8 meets Symfony
namespace Symfony\Component\HttpKernel;
interface HttpKernelInterface{ /**
* @return Response A Response instance*/
functionhandle(Request$request, $type=self::MASTER_REQUEST, $catch=true);}
-
7/31/2019 Symfony2 Meets Drupal
79/131
Drupal 8 meets Symfony
Request ResponseWorkflow
-
7/31/2019 Symfony2 Meets Drupal
80/131
Drupal 8 meets Symfony
Request request
-
7/31/2019 Symfony2 Meets Drupal
81/131
Drupal 8 meets Symfony
Request Responseresponse
response?
request
-
7/31/2019 Symfony2 Meets Drupal
82/131
Drupal 8 meets Symfony
Request resolvecontrollerrequest
-
7/31/2019 Symfony2 Meets Drupal
83/131
Drupal 8 meets Symfony
namespace Symfony\Component\HttpKernel\Controller;
interface ControllerResolverInterface{
functiongetController(Request$request);
functiongetArguments(Request$request, $controller);}
-
7/31/2019 Symfony2 Meets Drupal
84/131
Drupal 8 meets Symfony
Request controllerresolvecontrollerrequest
-
7/31/2019 Symfony2 Meets Drupal
85/131
Drupal 8 meets Symfony
Request controllerresolvecontrollerresolve
argumentsrequest
-
7/31/2019 Symfony2 Meets Drupal
86/131
Drupal 8 meets Symfony
RequestCall
Controllercontrollerresolve
controllerresolve
argumentsrequest
-
7/31/2019 Symfony2 Meets Drupal
87/131
Drupal 8 meets Symfony
Request ResponseresponseCall
Controllercontrollerresolve
controllerresolve
argumentsrequest
-
7/31/2019 Symfony2 Meets Drupal
88/131
Drupal 8 meets Symfony
Request ResponseresponseCall
Controllercontroller
view
resolvecontroller
resolveargumentsrequest
-
7/31/2019 Symfony2 Meets Drupal
89/131
Drupal 8 meets Symfony
Request Responseresponse
expection
exception
-
7/31/2019 Symfony2 Meets Drupal
90/131
Drupal 8 meets Symfony
Request Response
terminate
-
7/31/2019 Symfony2 Meets Drupal
91/131
Drupal 8 meets Symfony
CallController
Sub-Request
request
sub-response content
-
7/31/2019 Symfony2 Meets Drupal
92/131
Drupal 8 meets Symfony
Request ResponseresponseCall
Controller
response?
expectionSub-Request
terminate
controller
view
resolvecontroller
resolveargumentsrequest
exceptionsub-response content
$ t R t C ll ti ()
-
7/31/2019 Symfony2 Meets Drupal
93/131
Drupal 8 meets Symfony
$routes=newRouteCollection();$routes->add('hello', newRoute('/hello', array('_controller'=> function (Request$request) {
returnnewResponse(sprintf("Hello %s", $request->get('name')));})));
$request=Request::createFromGlobals();
$matcher=newUrlMatcher($routes, newRequestContext());
$dispatcher=newEventDispatcher();$dispatcher->addSubscriber(newRouterListener($matcher));
$resolver=newControllerResolver();$kernel=newHttpKernel($dispatcher, $resolver);$kernel->handle($request)->send();
-
7/31/2019 Symfony2 Meets Drupal
94/131
Drupal 8 meets Symfony
Symfonybuilt-inlisteners
http://www.flickr.com/photos/c_r_i_s/67306260
http://www.flickr.com/photos/c_r_i_s/67306260http://www.flickr.com/photos/c_r_i_s/67306260 -
7/31/2019 Symfony2 Meets Drupal
95/131
Drupal 8 meets Symfony
$handler=function ($exception) {returnnewResponse($exception->getMessage(), 500);
});
$dispatcher->addSubscriber(newExceptionListener($handler));
-
7/31/2019 Symfony2 Meets Drupal
96/131
Drupal 8 meets Symfony
$handler=function ($exception) { $handler=newExceptionHandler();
return$handler->createResponse($exception);
});
$dispatcher->addSubscriber(newExceptionListener($handler));
-
7/31/2019 Symfony2 Meets Drupal
97/131
Drupal 8 meets Symfony
-
7/31/2019 Symfony2 Meets Drupal
98/131
Drupal 8 meets Symfony
The default HttpKernel implementationmakes Drupal interoperable with
any other software using the same
http://www.flickr.com/photos/ynaffitx/4667769355
HTTP
http://www.flickr.com/photos/ynaffitx/4667769355http://www.flickr.com/photos/ynaffitx/4667769355 -
7/31/2019 Symfony2 Meets Drupal
99/131
Drupal 8 meets Symfony
http://www.flickr.com/photos/cmogle/2947179118
HTTP
Testing
http://www.flickr.com/photos/cmogle/2947179118http://www.flickr.com/photos/cmogle/2947179118 -
7/31/2019 Symfony2 Meets Drupal
100/131
Drupal 8 meets Symfony
use Symfony\Component\HttpKernel\Client;
$client=newClient($kernel);
$client->request('GET', '/hello/Fabien');
$response=$client->getResponse();
$this->assertEquals(200, $response->getStatusCode());
-
7/31/2019 Symfony2 Meets Drupal
101/131
Drupal 8 meets Symfony
use Symfony\Component\HttpKernel\Client;
$client=newClient($kernel);
$crawler=$client->request('GET', '/hello/Fabien');
$nodes=$crawler->filter('h1:contains("Fabien")');
$this->assertCount(1, $nodes);
HTTP
-
7/31/2019 Symfony2 Meets Drupal
102/131
http://www.flickr.com/photos/laserstars/908946494 Drupal 8 meets Symfony
Caching
Expiration
-
7/31/2019 Symfony2 Meets Drupal
103/131
Expiration
Cache-Control
Expires
Validation
-
7/31/2019 Symfony2 Meets Drupal
104/131
Validation
Last-ModifiedIf-Modified-Since
ETagIf-None-Match
-
7/31/2019 Symfony2 Meets Drupal
105/131
Drupal 8 meets Symfony
$response->setTtl(10);$response->setClientTtl(10);
// get the last modified date as fast as you can
-
7/31/2019 Symfony2 Meets Drupal
106/131
Drupal 8 meets Symfony
// get the last modified date as fast as you can$lastModified=...;
$response=newResponse();$response->setLastModified($lastModified);
if ($response->isNotModified($request)) {
return$response;}
// do the expensive work$response->setContent(...);
return$response;
-
7/31/2019 Symfony2 Meets Drupal
107/131
Drupal 8 meets Symfony
Expiration
wins overValidation
http://www.flickr.com/photos/hoyvinmayvin/4672922637
http://www.flickr.com/photos/hoyvinmayvin/4672922637http://www.flickr.com/photos/hoyvinmayvin/4672922637 -
7/31/2019 Symfony2 Meets Drupal
108/131
Drupal 8 meets Symfony
$kernel=newHttpKernel($dispatcher, $resolver);
$kernel=newHttpCache($kernel, newStore($cacheDir));
Varnish
-
7/31/2019 Symfony2 Meets Drupal
109/131
Drupal 8 meets Symfony
Varnish
The HTTPaccelerator
http://www.flickr.com/photos/stuckincustoms/3232133635
http://www.flickr.com/photos/stuckincustoms/3232133635http://www.flickr.com/photos/stuckincustoms/3232133635 -
7/31/2019 Symfony2 Meets Drupal
110/131
Drupal 8 meets Symfony
Using the default HttpKernelallows Drupal to benefit from
the many built-in features
http://www.flickr.com/photos/ynaffitx/4667769355
Edge
http://www.flickr.com/photos/ynaffitx/4667769355http://www.flickr.com/photos/ynaffitx/4667769355 -
7/31/2019 Symfony2 Meets Drupal
111/131
Drupal 8 meets Symfony
g
SideIncludes
ESI
http://www.w3.org/TR/esi-lang
h"p://www.flickr.com/photos/bored-now/2264811719
http://www.flickr.com/photos/bored-now/2264811719http://www.flickr.com/photos/bored-now/2264811719http://www.w3.org/TR/esi-langhttp://www.w3.org/TR/esi-lang -
7/31/2019 Symfony2 Meets Drupal
112/131
Drupal 8 meets Symfony
-
7/31/2019 Symfony2 Meets Drupal
113/131
Drupal 8 meets Symfony
HTTP Validation
-
7/31/2019 Symfony2 Meets Drupal
114/131
Drupal 8 meets Symfony
HTTP Expiration
HTTP Validation
-
7/31/2019 Symfony2 Meets Drupal
115/131
Drupal 8 meets Symfony
HTTP Expiration
-
7/31/2019 Symfony2 Meets Drupal
116/131
Drupal 8 meets Symfony
-
7/31/2019 Symfony2 Meets Drupal
117/131
Drupal 8 meets Symfony
CallController
Sub-Request
request
sub-response content
HTTP Expiration
-
7/31/2019 Symfony2 Meets Drupal
118/131
Drupal 8 meets Symfony
GET /foo HTTP/1.1Host: foo.org
GET /foo HTTP/1.1Host: foo.org
-
7/31/2019 Symfony2 Meets Drupal
119/131
GET /bar HTTP/1.1Host: foo.org
Lorem
ipsum
dolor
HTTP/1.1 200 OKC-C: s-maxage=600
Loremipsum
dolor
HTTP/1.1 200 OKC-C: s-maxage=5
Loremipsum
dolorsitamet,
Lorem
ipsum
dolor
HTTP/1.1 200 OK
GET /fooC-C: s-maxage=600
Lor
GET /barC-C: s-maxage=5
Lorem
GET /foo HTTP/1.1Host: foo.org
-
7/31/2019 Symfony2 Meets Drupal
120/131
Loremipsum
dolorsitamet,
Lorem
ipsum
dolor
HTTP/1.1 200 OK
GET /fooC-C: s-maxage=600
Lor
GET /barC-C: s-maxage=5
Lorem
GET /foo HTTP/1.1Host: foo.org
-
7/31/2019 Symfony2 Meets Drupal
121/131
GET /bar HTTP/1.1Host: foo.org
Loremipsum
dolor
HTTP/1.1 200 OKC-C: s-maxage=5
Loremipsum
dolorsitamet,
Lorem
ipsum
dolor
HTTP/1.1 200 OK
GET /fooC-C: s-maxage=600
Lor
GET /barC-C: s-maxage=5
Lorem
-
7/31/2019 Symfony2 Meets Drupal
122/131
Drupal 8 meets Symfony
$kernel=newHttpCache( $kernel, newStore($cacheDir),
newEsi());
Varnish
-
7/31/2019 Symfony2 Meets Drupal
123/131
Drupal 8 meets Symfony
http://www.flickr.com/photos/stuckincustoms/3232133635
Varnish
The HTTPaccelerator
http://www.flickr.com/photos/stuckincustoms/3232133635http://www.flickr.com/photos/stuckincustoms/3232133635 -
7/31/2019 Symfony2 Meets Drupal
124/131
Drupal 8 meets Symfony
The Symfony HttpKernel Componentprovides the building blocks
to create flexible, extensible, and scalable
HTTP-based frameworks
http://www.flickr.com/photos/ynaffitx/4667769355
http://www.flickr.com/photos/ynaffitx/4667769355http://www.flickr.com/photos/ynaffitx/4667769355 -
7/31/2019 Symfony2 Meets Drupal
125/131
Drupal 8 meets Symfony
The Symfony HttpKernel Componentleverages the HTTP specification
to make integration between projects easy
http://www.flickr.com/photos/ynaffitx/4667769355
http://symfony.com/components
http://www.flickr.com/photos/ynaffitx/4667769355http://www.flickr.com/photos/ynaffitx/4667769355http://symfony.com/componentshttp://symfony.com/components -
7/31/2019 Symfony2 Meets Drupal
126/131
Drupal 8 meets Symfony
DependencyInjectionEventDispatcher
HttpFoundation
DomCrawler
ClassLoader
CssSelector
HttpKernel
BrowserKit TemplatingTranslation
Filesystem
Serializer
ValidatorSecurity
Routing
ConsoleProcess
Config
Finder
Locale
Yaml
Formhttp://www.flickr.com/photos/ecstaticist/3860865429
Silex
http://www.flickr.com/photos/ecstaticist/3860865429http://www.flickr.com/photos/ecstaticist/3860865429 -
7/31/2019 Symfony2 Meets Drupal
127/131
Drupal 8 meets Symfony
Silex
https://github.com/fabpot/Silexhttp://silex.sensiolabs.org/http://www.flickr.com/photos/linhngan/2715287035
Build your own
http://www.flickr.com/photos/linhngan/2715287035http://www.flickr.com/photos/linhngan/2715287035https://github.com/fabpot/Silexhttps://github.com/fabpot/Silex -
7/31/2019 Symfony2 Meets Drupal
128/131
Drupal 8 meets Symfony
http://fabien.potencier.org/build-a-framework
y
framework
http://www.flickr.com/photos/linhngan/2715287035
http://www.flickr.com/photos/linhngan/2715287035http://www.flickr.com/photos/linhngan/2715287035http://fabien.potencier.org/build-a-frameworkhttp://fabien.potencier.org/build-a-framework -
7/31/2019 Symfony2 Meets Drupal
129/131
Drupal 8 meets Symfony
http://live.symfony.com/
http://live.symfony.com/http://live.symfony.com/ -
7/31/2019 Symfony2 Meets Drupal
130/131
Drupal 8 meets Symfony
The Symfony Components provides the low-levelbuilding blocks that you need to build a web product
so that YOU can focus on what matters most for Drupal
http://www.flickr.com/photos/ynaffitx/4667769355
@fabpot@l ith
http://www.flickr.com/photos/ynaffitx/4667769355http://www.flickr.com/photos/ynaffitx/4667769355 -
7/31/2019 Symfony2 Meets Drupal
131/131
@lsmith