0
Symfony2
Fabien Potencier
How many of you have already used symfony1?
How many of you have already played with Symfony2?
What is Symfony2?
A set of decoupled
and cohesive components
DependencyInjection
  EventDispatcher
  HttpFoundation
   OutputEscaper
    DomCrawler
    CssSelector
    Templating
    ...
git clone git://github.com/symfony/symfony.git
A set of decoupled
and cohesive components

    Autoloading
PEAR_Log   >   PEAR/Log.php
          Zend_Log   >   Zend/Log.php
Swift_Mime_Message   >   Swift/Mime/Message.php
     Twi...
SymfonyFoundationKernel
          Symfony/Foundation/Kernel.php

                DoctrineDBALDriver
              Doctrine...
require_once '.../Symfony/Framework/
UniversalClassLoader.php';

use SymfonyFrameworkUniversalClassLoader;

$loader = new ...
$loader->registerNamespaces(array(
  'Symfony' => '/path/to/symfony/src',
  'Doctrine' => '/path/to/doctrine/lib',
  'pdep...
$loader->registerPrefixes(array(
  'Swift_' => '/path/to/swiftmailer/lib/classes',
  'Zend_' => '/path/to/vendor/zend/libr...
A set of decoupled
and cohesive components

      Process
use SymfonyComponentProcessProcess;

$cmd = 'ssh 1.2.3.4 "ps waux"';

$process = new Process($cmd);
$process->run();

if (...
$cmd = 'ssh 1.2.3.4 "tail -f /some/log"';

$process = new Process($cmd);

$process->run(function ($type, $buffer) {
    ec...
use SymfonyComponentProcessPhpProcess;

$process = new PhpProcess(
    '<?php echo "hello"; ?>');
$process->run();

if (!$...
A set of decoupled
and cohesive components

    CssSelector
use SymfonyComponentCssSelectorParser;

Parser::cssToXpath('h4 > a:contains("foo")');
use SymfonyComponentCssSelectorParser;

$document = new DOMDocument();
$document->loadHTMLFile('...');
$xpath = new DOMXPa...
A set of decoupled
and cohesive components

       Finder
use SymfonyComponentFinderFinder;

$finder = new Finder();
$finder
    ->files()
    ->in(__DIR__)
    ->...()
    ->sortB...
$finder
    ->name('*.php')
    ->depth('<= 1')
    ->date('>= yesterday')
    ->size('<= 1K')
    ->filter(function (SplF...
foreach ($finder as $file) {
    print $file->getRealpath()."n";
}

$files = iterator_to_array($finder);

$count = iterato...
use SymfonyComponentFinderFinder;

$s3 = new Zend_Service_Amazon_S3($key, $sct);
$s3->registerStreamWrapper("s3");

$finde...
A set of decoupled
and cohesive components

      Routing
/blog.php?section=symfony&article_id=18475
web/
  index.php
/index.php/blog/2010/09/18/Symfony2-in-India
/blog/2010/09/18/Symfony2-in-India
/blog/:year/:month/:day/:slug
post:
    pattern: /blog/:year/:month/:day/:slug
    defaults:
      { _controller: BlogBundle:Post:show }
<routes>
    <route
      id="post"
      pattern="/blog/:year/:month/:day/:slug">
      <default key="_controller">
     ...
use SymfonyComponentRoutingRouteCollection;
use SymfonyComponentRoutingRoute;

$collection = new RouteCollection();

$rout...
$router
  ->match('/blog/2010/09/18/Symfony2-in-India')



$router
  ->generate('post', array('slug' => '...'))
post:
    pattern: /post/:slug
    defaults:
      { _controller: BlogBundle:Post:show }
$router
  ->generate('post', array('slug' => '...'))
An Object-Oriented abstraction
         on top of PHP
An Object-Oriented abstraction
         on top of PHP

          Request
use SymfonyComponentHttpFoundationRequest;

$request = new Request();

// get a $_GET parameter
$request->query->get('page...
// get a $_FILE parameter
$f = $request->files->get('image');

// $f is an instance of
// SymfonyComponentHttpFoundationFi...
new Request();

new Request(
    $_GET, $_POST, array(),
    $_COOKIE, $_FILES, $_SERVER
);

Request::create('/hello/Fabie...
An Object-Oriented abstraction
         on top of PHP

          Session
$session = $request->getSession();

$session->set('foo', 'bar');
$session->get('foo');

$session->setFlash('notice', 'Cong...
An Object-Oriented abstraction
         on top of PHP

         Response
use SymfonyComponentHttpFoundationResponse;

$response = new Response('Hello World', 200,
  array('Content-Type' => 'text/...
An Object-Oriented abstraction
       of the HTTP dialog
A MVC Web Framework
The Symfony2 MVC Philosophy
Be as easy as possible for newcomers
and as flexible as possible for advanced users
MVC
http://symfony-reloaded.org/

http://symfony-reloaded.org/downloads/
          sandbox_2_0_PR3.zip
post:
    pattern: /hello/:name
    defaults:
      { _controller: HelloBundle:Hello:index }

namespace ApplicationHelloBu...
namespace ApplicationHelloBundleController;

use SymfonyBundleFrameworkBundleController;

class HelloController extends Co...
Hello <?php echo $name ?>!
<?php $view->extend('HelloBundle::layout') ?>

Hello <?php echo $name ?>!
<html>
    <head>
         <title>
           <?php $view['slots']->output('title') ?>
         </title>
    </head>
    <...
slot
                    title

         Lorem	
  ipsum	
  dolor	
  sit	
  amet,	
  consectetur	
  adipiscing	
  elit.	
  ...
{% extends "HelloBundle::layout" %}

{% block content %}
    Hello {{ name }}!
{% endblock %}
<html>
    <head>
        <title>
            {% block title %}{% endblock %}
        </title>
    </head>
    <body>
    ...
~ PAC / HMVC




http://en.wikipedia.org/wiki/Presentation-abstraction-control
Lorem	
  ipsum	
  dolor	
  sit	
  amet,	
  consectetur	
                 Lorem	
  ipsum	
  dolor	
  sit	
  
layout   adipi...
public function indexAction($name)
{
    $embedded = $this['controller_resolver']
        ->render('HelloBundle:Hello:foo'...
<?php $view->extend('...:layout') ?>

Lorem ipsum...

<?php echo $view['actions']
    ->render('HelloBundle:Hello:foo',
  ...
Bundles
.../
  SomeBundle/
     Controller/
     Entity/
     Resources/
       config/
       views/
     SomeBundle.php
     Tes...
public function registerBundleDirs()
{
    return array(
        'Application'    => __DIR__.'/../src/Application',
      ...
$this->render('SomeBundle:Hello:index', $params)
hello:
  pattern: /hello/:name
  defaults:
    { _controller: SomeBundle:Hello:index }
SomeBundle can be any of


ApplicationSomeBundle
BundleSomeBundle
SymfonyBundleSomeBundle
Environments
Developers     Customer     End Users




Development     Staging      Production
Environment   Environment   Environment
cache         cache          cache

  debug	
       debug	
        debug	
  

   logs	
        logs	
         logs	
  

  ...
# config/config.yml
doctrine.dbal:
    dbname:    mydbname
    user:      root
    password: %doctrine.dbal_password%

swi...
# config/config_dev.yml
imports:
    - { resource: config.yml }

doctrine.dbal:
    password: null

swift.mailer:
    tran...
# Doctrine Configuration
doctrine.dbal:
    dbname:    xxxxxxxx
    user:      xxxxxxxx
    password: ~

# Swiftmailer Con...
<!-- Doctrine Configuration -->
<doctrine:dbal dbname="xxxxxxxx" user="xxxxxxxx"
password="" />

<!-- Swiftmailer Configur...
// Doctrine Configuration
$container->loadFromExtension('doctrine', 'dbal', array(
    'dbname'   => 'xxxxxxxx',
    'user...
Dependency Injection Container
Third-party libraries integration
     Unified Configuration
# Twig Configuration
twig.config:
    auto_reload: true

# Zend Logger Configuration
zend.logger:
    priority: debug
    ...
Configuration formats
XML, YAML, PHP, INI, or Annotations
   Parameters management
         Fast (cached)
          Inherit...
<doctrine:dbal
   dbname="sfweb"
   username="root"
   password="SuperSecretPasswordThatAnyoneCanSee"
/>
in a .htaccess or httpd.conf file
SetEnv SYMFONY__DOCTRINE__DBAL__PASSWORD "foobar"
                        %doctrine.dbal....
<doctrine:dbal
   dbname="sfweb"
   username="root"
   password="%doctrine.dbal.password%"
/>
Developer Tools
INFO: Matched route "blog_home" (parameters: array ( '_bundle' =>
'BlogBundle', '_controller' => 'Post', '_action' => 'ind...
INFO: Matched route "blog_post" (parameters: array ( '_bundle' =>
'BlogBundle', '_controller' => 'Post', '_action' => 'sho...
DEBUG: Notifying (until) event "core.request" to listener "(SymfonyFrameworkWebBundleListenerRequestParser, resolve)"
INFO...
Security

XSS / CSRF / SQL Injection
Functional Tests
$client = $this->createClient();

$crawler = $client->request(
  'GET', '/hello/Fabien');

$this->assertTrue($crawler->fil...
$this->assertEquals(
  10,
  $crawler->filter('div.hentry')->count());

$this->assertTrue(
  $client->getResponse()->isSuc...
$crawler = $client->request(
    'GET', 'hello/Lucas'
);
$link = $crawler->selectLink("Greet Lucas");

$client->click($link);
$form = $crawler->selectButton('submit');

$client->submit($form, array(
    'name'         => 'Lucas',
    'country'     ...
$harry = $this->createClient();
$sally = $this->createClient();

$harry->request('POST', '/say/sally/Hello');
$sally->requ...
$harry = $this->createClient();
$sally = $this->createClient();

$harry->insulate();
$sally->insulate();

$harry->request(...
Caching
HTTP Expiration / HTTP Validation
$response->setSharedMaxAge(...);
$response->setTtl(...);
$response->setMaxAge(...);
$response->setClientTtl(...);
$respons...
Cache-Control: s-maxage=10
public function showAction()
{
  // ...

    $response = $this->render('...', $vars);

    $response->setSharedMaxAge(10);...
Symfony 2 comes built-in with an HTTP accelerator
cacheable for 10 seconds
                                                                            cacheable for 5 secon...
cacheable for 10 seconds

<?php $view->extend('...:layout') ?>

<?php $view['slots']->start('sidebar') ?> 5 seconds
      ...
$view['actions']->render('HelloBundle:Hello:foo',
    array('name' => $name),
    array('standalone' => true)
)
Lorem	
  ipsum	
  dolor	
  sit	
  amet,	
  consectetur	
              Lorem	
  ipsum	
  dolor	
  sit	
  
adipiscing	
  eli...
<esi:include src="..." />
Lorem	
  ipsum	
  dolor	
  sit	
  amet,	
  consectetur	
  
adipiscing	
  elit.	
  In	
  vel	
  n...
ESI… or Edge Side Includes
Lorem	
  ipsum	
  
                                                                      dolor	
  sit	
  
                ...
Web Server




                      Symfony2
                        app
Requests




           Response
Web Server

               Symfony2 HTTP proxy


                      Symfony2
                        app
Requests




 ...
Reverse proxy

                      Web Server




                      Symfony2
                        app
Requests


...
Extensibility
Request


      core.request


           getController()


      core.controller


           getArguments()


      core...
Request


      core.request


           getController()


      core.controller
                             core.except...
SwiftmailerBundle     DoctrineBundle


                                 ZendBundle               ...


             Framew...
Questions?
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
Upcoming SlideShare
Loading in...5
×

Symfony2 - WebExpo 2010

4,147

Published on

Published in: Technology
2 Comments
3 Likes
Statistics
Notes
No Downloads
Views
Total Views
4,147
On Slideshare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
59
Comments
2
Likes
3
Embeds 0
No embeds

No notes for slide

Transcript of "Symfony2 - WebExpo 2010"

  1. 1. Symfony2 Fabien Potencier
  2. 2. How many of you have already used symfony1?
  3. 3. How many of you have already played with Symfony2?
  4. 4. What is Symfony2?
  5. 5. A set of decoupled and cohesive components
  6. 6. DependencyInjection EventDispatcher HttpFoundation OutputEscaper DomCrawler CssSelector Templating HttpKernel BrowserKit Validator Routing Console Process Finder Form Yaml
  7. 7. git clone git://github.com/symfony/symfony.git
  8. 8. A set of decoupled and cohesive components Autoloading
  9. 9. PEAR_Log > PEAR/Log.php Zend_Log > Zend/Log.php Swift_Mime_Message > Swift/Mime/Message.php Twig_Node_For > Twig/Node/For.php
  10. 10. SymfonyFoundationKernel Symfony/Foundation/Kernel.php DoctrineDBALDriver Doctrine/DBAL/Driver.php pdependreflectionReflectionSession pdepend/reflection/ReflectionSession.php http://groups.google.com/group/php-standards/web/psr-0-final-proposal  
  11. 11. require_once '.../Symfony/Framework/ UniversalClassLoader.php'; use SymfonyFrameworkUniversalClassLoader; $loader = new UniversalClassLoader(); $loader->register();
  12. 12. $loader->registerNamespaces(array( 'Symfony' => '/path/to/symfony/src', 'Doctrine' => '/path/to/doctrine/lib', 'pdepend' => '/path/to/reflection/source', )); PHP 5.3 technical interoperability standards
  13. 13. $loader->registerPrefixes(array( 'Swift_' => '/path/to/swiftmailer/lib/classes', 'Zend_' => '/path/to/vendor/zend/library', )); PEAR style
  14. 14. A set of decoupled and cohesive components Process
  15. 15. use SymfonyComponentProcessProcess; $cmd = 'ssh 1.2.3.4 "ps waux"'; $process = new Process($cmd); $process->run(); if (!$process->isSuccessful()) { throw new RuntimeException( $process->getErrorOutput()); } echo $process->getOutput();
  16. 16. $cmd = 'ssh 1.2.3.4 "tail -f /some/log"'; $process = new Process($cmd); $process->run(function ($type, $buffer) { echo $buffer; });
  17. 17. use SymfonyComponentProcessPhpProcess; $process = new PhpProcess( '<?php echo "hello"; ?>'); $process->run(); if (!$process->isSuccessful()) { throw new RuntimeException( $process->getErrorOutput()); } echo $process->getOutput();
  18. 18. A set of decoupled and cohesive components CssSelector
  19. 19. use SymfonyComponentCssSelectorParser; Parser::cssToXpath('h4 > a:contains("foo")');
  20. 20. use SymfonyComponentCssSelectorParser; $document = new DOMDocument(); $document->loadHTMLFile('...'); $xpath = new DOMXPath($document); $expr = Parser::cssToXpath('a.smart'); $nodes = $xpath->query($expr); foreach ($nodes as $node) { printf("%s (%s)n", $node->nodeValue, $node- >getAttribute('href')); }
  21. 21. A set of decoupled and cohesive components Finder
  22. 22. use SymfonyComponentFinderFinder; $finder = new Finder(); $finder ->files() ->in(__DIR__) ->...() ->sortByName() ;
  23. 23. $finder ->name('*.php') ->depth('<= 1') ->date('>= yesterday') ->size('<= 1K') ->filter(function (SplFileInfo $file) { return strlen($file->getBasename()) < 9; }) ;
  24. 24. foreach ($finder as $file) { print $file->getRealpath()."n"; } $files = iterator_to_array($finder); $count = iterator_count($finder);
  25. 25. use SymfonyComponentFinderFinder; $s3 = new Zend_Service_Amazon_S3($key, $sct); $s3->registerStreamWrapper("s3"); $finder = new Finder(); $finder ->name('photos*') ->size('< 100K') ->date('since 1 hour ago') ->in('s3://bucket-name') ;
  26. 26. A set of decoupled and cohesive components Routing
  27. 27. /blog.php?section=symfony&article_id=18475
  28. 28. web/ index.php
  29. 29. /index.php/blog/2010/09/18/Symfony2-in-India
  30. 30. /blog/2010/09/18/Symfony2-in-India
  31. 31. /blog/:year/:month/:day/:slug
  32. 32. post: pattern: /blog/:year/:month/:day/:slug defaults: { _controller: BlogBundle:Post:show }
  33. 33. <routes> <route id="post" pattern="/blog/:year/:month/:day/:slug"> <default key="_controller"> BlogBundle:Post:show </default> </route> </routes>
  34. 34. use SymfonyComponentRoutingRouteCollection; use SymfonyComponentRoutingRoute; $collection = new RouteCollection(); $route = new Route( '/blog/:year/:month/:day/:slug', array('_controller' => 'BlogBundle:Post:show')); $collection->addRoute('post', $route); return $collection;
  35. 35. $router ->match('/blog/2010/09/18/Symfony2-in-India') $router ->generate('post', array('slug' => '...'))
  36. 36. post: pattern: /post/:slug defaults: { _controller: BlogBundle:Post:show }
  37. 37. $router ->generate('post', array('slug' => '...'))
  38. 38. An Object-Oriented abstraction on top of PHP
  39. 39. An Object-Oriented abstraction on top of PHP Request
  40. 40. use SymfonyComponentHttpFoundationRequest; $request = new Request(); // get a $_GET parameter $request->query->get('page'); // get a $_POST parameter $request->request->get('page'); // get a $_COOKIE parameter $request->cookies->get('name'); $request->getPreferredLanguage(array('en', 'fr')); $request->isXmlHttpRequest();
  41. 41. // get a $_FILE parameter $f = $request->files->get('image'); // $f is an instance of // SymfonyComponentHttpFoundationFileUploadedFile // guess extension, based on the mime type $n = '/path/to/file'.$file->getDefaultExtension(); $f->move($n);
  42. 42. new Request(); new Request( $_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER ); Request::create('/hello/Fabien', 'GET');
  43. 43. An Object-Oriented abstraction on top of PHP Session
  44. 44. $session = $request->getSession(); $session->set('foo', 'bar'); $session->get('foo'); $session->setFlash('notice', 'Congratulations!');
  45. 45. An Object-Oriented abstraction on top of PHP Response
  46. 46. use SymfonyComponentHttpFoundationResponse; $response = new Response('Hello World', 200, array('Content-Type' => 'text/plain')); $response->send(); $response->setHeader('Content-Type', 'text/ plain'); $response->setCookie('foo', 'bar'); $response->setContent('Hello World'); $response->setStatusCode(200);
  47. 47. An Object-Oriented abstraction of the HTTP dialog
  48. 48. A MVC Web Framework
  49. 49. The Symfony2 MVC Philosophy
  50. 50. Be as easy as possible for newcomers and as flexible as possible for advanced users
  51. 51. MVC
  52. 52. http://symfony-reloaded.org/ http://symfony-reloaded.org/downloads/ sandbox_2_0_PR3.zip
  53. 53. post: pattern: /hello/:name defaults: { _controller: HelloBundle:Hello:index } namespace ApplicationHelloBundleController; use SymfonyBundleFrameworkBundleController; class HelloController extends Controller { public function indexAction($name) { return new Response('Hello '.$name); } }
  54. 54. namespace ApplicationHelloBundleController; use SymfonyBundleFrameworkBundleController; class HelloController extends Controller { public function indexAction($name) { // Get things from the Model return $this->render( 'HelloBundle:Hello:index', array('name' => $name) ); } }
  55. 55. Hello <?php echo $name ?>!
  56. 56. <?php $view->extend('HelloBundle::layout') ?> Hello <?php echo $name ?>!
  57. 57. <html> <head> <title> <?php $view['slots']->output('title') ?> </title> </head> <body> <?php $view['slots']->output('_content') ?> </body> </html>
  58. 58. slot title Lorem  ipsum  dolor  sit  amet,  consectetur  adipiscing  elit.  In  vel   _content Lorem  ipsum  dolor  sit  amet,  consectetur  adipiscing  elit.  In  vel  nulla  arcu,   vitae  cursus  nunc.  Integer  semper  turpis  et  enim  por6tor  iaculis.  Nulla   facilisi.  Lorem  ipsum  dolor  sit  amet,  consectetur  adipiscing  elit.  Mauris   vehicula  ves;bulum  dictum.  Aenean  non  velit  tortor.  Nullam  adipiscing   malesuada  aliquam.  Mauris  dignissim,  urna  quis  iaculis  tempus,  justo   layout libero  por6tor  est,  nec  eleifend  est  elit  vitae  ante.  Curabitur  interdum   luctus  metus,  in  pulvinar  lectus  rutrum  sit  amet.  Duis  gravida,  metus  in   dictum  eleifend,  dolor  risus  ;ncidunt  ligula,  non  volutpat  nulla  sapien  in   elit.  Nulla  rutrum  erat  id  neque  suscipit  eu  ultricies  odio  sollicitudin.   Aliquam  a  mi  vel  eros  placerat  hendrerit.  Phasellus  por6tor,  augue  sit   amet  vulputate  venena;s,  dui  leo  commodo  odio,  a  euismod  turpis   ligula  in  elit.     slot
  59. 59. {% extends "HelloBundle::layout" %} {% block content %} Hello {{ name }}! {% endblock %}
  60. 60. <html> <head> <title> {% block title %}{% endblock %} </title> </head> <body> {% block body %}{% endblock %} </body> </html>
  61. 61. ~ PAC / HMVC http://en.wikipedia.org/wiki/Presentation-abstraction-control
  62. 62. Lorem  ipsum  dolor  sit  amet,  consectetur   Lorem  ipsum  dolor  sit   layout adipiscing  elit.  In  vel  nulla  arcu,  vitae   amet,  consectetur   cursus  nunc.  Integer  semper  turpis  et  enim   adipiscing  elit.  In  vel  nulla   por6tor  iaculis.  Nulla  facilisi.  Lorem  ipsum   arcu,  vitae  cursus  nunc.   dolor  sit  amet,  consectetur  adipiscing  elit.   Integer  semper  turpis  et   Mauris  vehicula  ves;bulum  dictum.   enim  por6tor  iaculis.   Aenean  non  velit  tortor.  Nullam  adipiscing   Nulla  facilisi.  Lorem  ipsum   malesuada  aliquam.  Mauris  dignissim,  urna   dolor  sit  amet,   quis  iaculis  tempus,  justo  libero  por6tor   consectetur  adipiscing  elit.   est,  nec  eleifend  est  elit  vitae  ante.   Mauris  vehicula   Curabitur  interdum  luctus  metus,  in   ves;bulum  dictum.   pulvinar  lectus  rutrum  sit  amet.  Duis   Aenean  non  velit  tortor.   gravida,  metus  in  dictum  eleifend,  dolor   Nullam  adipiscing   risus  ;ncidunt  ligula,  non  volutpat  nulla   malesuada  aliquam.   sapien  imain controller n  elit.  Nulla  rutrum  erat  id  neque   embedded MVC Mauris  dignissim,  urna   suscipit  eu  ultricies  odio  sollicitudin.   (_content slot) quis  iaculis  tempus,  justo   controller Aliquam  a  mi  vel  eros  placerat  hendrerit.   libero  por6tor  est,  nec   Phasellus  por6tor,  augue  sit  amet   eleifend  est  elit  vitae  ante.   vulputate  venena;s,  dui  leo  commodo   Curabitur  interdum  luctus   odio,  a  euismod  turpis  ligula  in  elit.     metus.  
  63. 63. public function indexAction($name) { $embedded = $this['controller_resolver'] ->render('HelloBundle:Hello:foo', array('name' => $name)); return $this->render( 'HelloBundle:Hello:index', array( 'name' => $name, 'embedded' => $embedded, ) ); }
  64. 64. <?php $view->extend('...:layout') ?> Lorem ipsum... <?php echo $view['actions'] ->render('HelloBundle:Hello:foo', array('name' => $name)) ?> Lorem ipsum...
  65. 65. Bundles
  66. 66. .../ SomeBundle/ Controller/ Entity/ Resources/ config/ views/ SomeBundle.php Tests/
  67. 67. public function registerBundleDirs() { return array( 'Application' => __DIR__.'/../src/Application', 'Bundle' => __DIR__.'/../src/Bundle', 'SymfonyBundle' => __DIR__.'/../src/vendor/ symfony/src/Symfony/Bundle', ); }
  68. 68. $this->render('SomeBundle:Hello:index', $params)
  69. 69. hello: pattern: /hello/:name defaults: { _controller: SomeBundle:Hello:index }
  70. 70. SomeBundle can be any of ApplicationSomeBundle BundleSomeBundle SymfonyBundleSomeBundle
  71. 71. Environments
  72. 72. Developers Customer End Users Development Staging Production Environment Environment Environment
  73. 73. cache cache cache debug   debug   debug   logs   logs   logs   stats stats stats Development Staging Production Environment Environment Environment
  74. 74. # config/config.yml doctrine.dbal: dbname: mydbname user: root password: %doctrine.dbal_password% swift.mailer: transport: smtp host: localhost
  75. 75. # config/config_dev.yml imports: - { resource: config.yml } doctrine.dbal: password: null swift.mailer: transport: gmail username: xxxxxxxx password: xxxxxxxx
  76. 76. # Doctrine Configuration doctrine.dbal: dbname: xxxxxxxx user: xxxxxxxx password: ~ # Swiftmailer Configuration swift.mailer: transport: smtp encryption: ssl auth_mode: login host: smtp.gmail.com username: xxxxxxxx password: xxxxxxxx
  77. 77. <!-- Doctrine Configuration --> <doctrine:dbal dbname="xxxxxxxx" user="xxxxxxxx" password="" /> <!-- Swiftmailer Configuration --> <swift:mailer transport="smtp" encryption="ssl" auth_mode="login" host="smtp.gmail.com" username="xxxxxxxx" password="xxxxxxxx" />
  78. 78. // Doctrine Configuration $container->loadFromExtension('doctrine', 'dbal', array( 'dbname' => 'xxxxxxxx', 'user' => 'xxxxxxxx', 'password' => '', )); // Swiftmailer Configuration $container->loadFromExtension('swift', 'mailer', array( 'transport' => "smtp", 'encryption' => "ssl", 'auth_mode' => "login", 'host' => "smtp.gmail.com", 'username' => "xxxxxxxx", 'password' => "xxxxxxxx", ));
  79. 79. Dependency Injection Container
  80. 80. Third-party libraries integration Unified Configuration
  81. 81. # Twig Configuration twig.config: auto_reload: true # Zend Logger Configuration zend.logger: priority: debug path: %kernel.root_dir%/logs/ %kernel.environment%.log
  82. 82. Configuration formats XML, YAML, PHP, INI, or Annotations Parameters management Fast (cached) Inheritance Sensitive data security …
  83. 83. <doctrine:dbal dbname="sfweb" username="root" password="SuperSecretPasswordThatAnyoneCanSee" />
  84. 84. in a .htaccess or httpd.conf file SetEnv SYMFONY__DOCTRINE__DBAL__PASSWORD "foobar" %doctrine.dbal.password%
  85. 85. <doctrine:dbal dbname="sfweb" username="root" password="%doctrine.dbal.password%" />
  86. 86. Developer Tools
  87. 87. INFO: Matched route "blog_home" (parameters: array ( '_bundle' => 'BlogBundle', '_controller' => 'Post', '_action' => 'index', '_route' => 'blog_home',)) INFO: Using controller "BundleBlogBundleController PostController::indexAction" INFO: SELECT s0_.id AS id0, s0_.title AS title1, s0_.html_body AS html_body2, s0_.excerpt AS excerpt3, s0_.published_at AS published_at4 FROM sf_weblog_post s0_ ORDER BY s0_.published_at DESC LIMIT 10 (array ())
  88. 88. INFO: Matched route "blog_post" (parameters: array ( '_bundle' => 'BlogBundle', '_controller' => 'Post', '_action' => 'show', '_format' => 'html', 'id' => '3456', '_route' => 'blog_post',)) INFO: Using controller "BundleBlogBundleController PostController::showAction » INFO: SELECT s0_.id AS id0, s0_.title AS title1, s0_.html_body AS html_body2, s0_.excerpt AS excerpt3, s0_.published_at AS published_at4 FROM sf_weblog_post s0_ WHERE s0_.id = ? (array ( 0 => '3456',)) ERR: Post "3456" not found! (No result was found for query although at least one row was expected.) (uncaught SymfonyComponentsRequestHandlerException NotFoundHttpException exception) INFO: Using controller "SymfonyFrameworkWebBundleController ExceptionController::exceptionAction"
  89. 89. DEBUG: Notifying (until) event "core.request" to listener "(SymfonyFrameworkWebBundleListenerRequestParser, resolve)" INFO: Matched route "blog_post" (parameters: array ( '_bundle' => 'BlogBundle', '_controller' => 'Post', '_action' => 'show', '_format' => 'html', 'id' => '3456', '_route' => 'blog_post',)) DEBUG: Notifying (until) event "core.load_controller" to listener "(SymfonyFrameworkWebBundleListenerControllerLoader, resolve)" INFO: Using controller "BundleBlogBundleControllerPostController::showAction" DEBUG: Listener "(SymfonyFrameworkWebBundleListenerControllerLoader, resolve)" processed the event "core.load_controller" INFO: Trying to get post "3456" from database INFO: SELECT s0_.id AS id0, s0_.title AS title1, s0_.html_body AS html_body2, s0_.excerpt AS excerpt3, s0_.published_at AS published_at4 FROM sf_weblog_post s0_ WHERE s0_.id = ? (array ( 0 => '3456',)) DEBUG: Notifying (until) event "core.exception" to listener "(SymfonyFrameworkWebBundleListenerExceptionHandler, handle)" ERR: Post "3456" not found! (No result was found for query although at least one row was expected.) (uncaught SymfonyComponents RequestHandlerExceptionNotFoundHttpException exception) DEBUG: Notifying (until) event "core.request" to listener "(SymfonyFrameworkWebBundleListenerRequestParser, resolve)" DEBUG: Notifying (until) event "core.load_controller" to listener "(SymfonyFrameworkWebBundleListenerControllerLoader, resolve)" INFO: Using controller "SymfonyFrameworkWebBundleControllerExceptionController::exceptionAction" DEBUG: Listener "(SymfonyFrameworkWebBundleListenerControllerLoader, resolve)" processed the event "core.load_controller" DEBUG: Notifying (filter) event "core.response" to listener "(SymfonyFrameworkWebBundleListenerResponseFilter, filter)" DEBUG: Notifying (filter) event "core.response" to listener "(SymfonyFrameworkWebBundleDebugDataCollector DataCollectorManager, handle)" DEBUG: Notifying (filter) event "core.response" to listener "(SymfonyFrameworkWebBundleDebugWebDebugToolbar, handle)" DEBUG: Listener "(SymfonyFrameworkWebBundleListenerExceptionHandler, handle)" processed the event "core.exception" DEBUG: Notifying (filter) event "core.response" to listener "(SymfonyFrameworkWebBundleListenerResponseFilter, filter)" DEBUG: Notifying (filter) event "core.response" to listener "(SymfonyFrameworkWebBundleDebugDataCollector DataCollectorManager, handle)" DEBUG: Notifying (filter) event "core.response" to listener "(SymfonyFrameworkWebBundleDebugWebDebugToolbar, handle)"
  90. 90. Security XSS / CSRF / SQL Injection
  91. 91. Functional Tests
  92. 92. $client = $this->createClient(); $crawler = $client->request( 'GET', '/hello/Fabien'); $this->assertTrue($crawler->filter( 'html:contains("Hello Fabien")')->count());
  93. 93. $this->assertEquals( 10, $crawler->filter('div.hentry')->count()); $this->assertTrue( $client->getResponse()->isSuccessful());
  94. 94. $crawler = $client->request( 'GET', 'hello/Lucas' );
  95. 95. $link = $crawler->selectLink("Greet Lucas"); $client->click($link);
  96. 96. $form = $crawler->selectButton('submit'); $client->submit($form, array( 'name' => 'Lucas', 'country' => 'France', 'like_symfony' => true, 'photo' => '/path/to/lucas.jpg', ));
  97. 97. $harry = $this->createClient(); $sally = $this->createClient(); $harry->request('POST', '/say/sally/Hello'); $sally->request('GET', '/messages'); $this->assertEquals(201, $harry->getResponse()->getStatusCode()); $this->assertRegExp('/Hello/', $sally->getResponse()->getContent());
  98. 98. $harry = $this->createClient(); $sally = $this->createClient(); $harry->insulate(); $sally->insulate(); $harry->request('POST', '/say/sally/Hello'); $sally->request('GET', '/messages'); $this->assertEquals(201, $harry->getResponse()->getStatusCode()); $this->assertRegExp('/Hello/', $sally->getResponse()->getContent());
  99. 99. Caching
  100. 100. HTTP Expiration / HTTP Validation
  101. 101. $response->setSharedMaxAge(...); $response->setTtl(...); $response->setMaxAge(...); $response->setClientTtl(...); $response->setExpires(...); $response->setETag(...); $response->setLastModified(...);
  102. 102. Cache-Control: s-maxage=10
  103. 103. public function showAction() { // ... $response = $this->render('...', $vars); $response->setSharedMaxAge(10); return $response; }
  104. 104. Symfony 2 comes built-in with an HTTP accelerator
  105. 105. cacheable for 10 seconds cacheable for 5 seconds Lorem  ipsum  dolor  sit  amet,  consectetur   Lorem  ipsum  dolor  sit   layout adipiscing  elit.  In  vel  nulla  arcu,  vitae   amet,  consectetur   cursus  nunc.  Integer  semper  turpis  et  enim   adipiscing  elit.  In  vel  nulla   por6tor  iaculis.  Nulla  facilisi.  Lorem  ipsum   arcu,  vitae  cursus  nunc.   dolor  sit  amet,  consectetur  adipiscing  elit.   Integer  semper  turpis  et   Mauris  vehicula  ves;bulum  dictum.   enim  por6tor  iaculis.   Aenean  non  velit  tortor.  Nullam  adipiscing   Nulla  facilisi.  Lorem  ipsum   malesuada  aliquam.  Mauris  dignissim,  urna   dolor  sit  amet,   quis  iaculis  tempus,  justo  libero  por6tor   consectetur  adipiscing  elit.   est,  nec  eleifend  est  elit  vitae  ante.   Mauris  vehicula   Curabitur  interdum  luctus  metus,  in   ves;bulum  dictum.   pulvinar  lectus  rutrum  sit  amet.  Duis   Aenean  non  velit  tortor.   gravida,  metus  in  dictum  eleifend,  dolor   Nullam  adipiscing   risus  ;ncidunt  ligula,  non  volutpat  nulla   malesuada  aliquam.   sapien  main Nulla  rutrum  erat  id  neque   in  elit.   Mauris  embeddedurna   dignissim,   suscipit  eu  ultricies  odio  sollicitudin.   controller quis  iaculis  tempus,  justo   controller Aliquam  a  mi  vel  eros  placerat  hendrerit.   libero  por6tor  est,  nec   Phasellus  por6tor,  augue  sit  amet   eleifend  est  elit  vitae  ante.   vulputate  venena;s,  dui  leo  commodo   Curabitur  interdum  luctus   odio,  a  euismod  turpis  ligula  in  elit.     metus.  
  106. 106. cacheable for 10 seconds <?php $view->extend('...:layout') ?> <?php $view['slots']->start('sidebar') ?> 5 seconds cacheable for <?php echo $view['actions']->render('...:foo') ?> <?php $view['slots']->stop() ?>
  107. 107. $view['actions']->render('HelloBundle:Hello:foo', array('name' => $name), array('standalone' => true) )
  108. 108. Lorem  ipsum  dolor  sit  amet,  consectetur   Lorem  ipsum  dolor  sit   adipiscing  elit.  In  vel  nulla  arcu,  vitae   amet,  consectetur   cursus  nunc.  Integer  semper  turpis  et  enim   adipiscing  elit.  In  vel  nulla   por6tor  iaculis.  Nulla  facilisi.  Lorem  ipsum   arcu,  vitae  cursus  nunc.   dolor  sit  amet,  consectetur  adipiscing  elit.   Integer  semper  turpis  et   Mauris  vehicula  ves;bulum  dictum.   enim  por6tor  iaculis.   Aenean  non  velit  tortor.  Nullam  adipiscing   Nulla  facilisi.  Lorem  ipsum   malesuada  aliquam.  Mauris  dignissim,  urna   dolor  sit  amet,   quis  iaculis  tempus,  justo  libero  por6tor   consectetur  adipiscing  elit.   est,  nec  eleifend  est  elit  vitae  ante.   Mauris  vehicula   Curabitur  interdum  luctus  metus,  in   ves;bulum  dictum.   pulvinar  lectus  rutrum  sit  amet.  Duis   Aenean  non  velit  tortor.   gravida,  metus  in  dictum  eleifend,  dolor   Nullam  adipiscing   risus  ;ncidunt  ligula,  non  volutpat  nulla   malesuada  aliquam.   sapien  in  elit.  Nulla  rutrum  erat  id  neque   Mauris  dignissim,  urna   suscipit  eu  ultricies  odio  sollicitudin.   quis  iaculis  tempus,  justo   Aliquam  a  mi  vel  eros  placerat  hendrerit.   libero  por6tor  est,  nec   Phasellus  por6tor,  augue  sit  amet   eleifend  est  elit  vitae  ante.   vulputate  venena;s,  dui  leo  commodo   Curabitur  interdum  luctus   odio,  a  euismod  turpis  ligula  in  elit.     metus.  
  109. 109. <esi:include src="..." /> Lorem  ipsum  dolor  sit  amet,  consectetur   adipiscing  elit.  In  vel  nulla  arcu,  vitae   cursus  nunc.  Integer  semper  turpis  et  enim   por6tor  iaculis.  Nulla  facilisi.  Lorem  ipsum   dolor  sit  amet,  consectetur  adipiscing  elit.   Mauris  vehicula  ves;bulum  dictum.   Aenean  non  velit  tortor.  Nullam  adipiscing   malesuada  aliquam.  Mauris  dignissim,  urna   quis  iaculis  tempus,  justo  libero  por6tor   est,  nec  eleifend  est  elit  vitae  ante.   Curabitur  interdum  luctus  metus,  in   pulvinar  lectus  rutrum  sit  amet.  Duis   gravida,  metus  in  dictum  eleifend,  dolor   risus  ;ncidunt  ligula,  non  volutpat  nulla   sapien  in  elit.  Nulla  rutrum  erat  id  neque   suscipit  eu  ultricies  odio  sollicitudin.   Aliquam  a  mi  vel  eros  placerat  hendrerit.   Phasellus  por6tor,  augue  sit  amet   vulputate  venena;s,  dui  leo  commodo   odio,  a  euismod  turpis  ligula  in  elit.    
  110. 110. ESI… or Edge Side Includes
  111. 111. Lorem  ipsum   dolor  sit   amet,     1 2 Symfony2 Application Lorem   ipsum   Reverse Proxy dolor   Client 3 Lorem  ipsum   Lorem   dolor  sit   ipsum   amet,     dolor   4
  112. 112. Web Server Symfony2 app Requests Response
  113. 113. Web Server Symfony2 HTTP proxy Symfony2 app Requests Response
  114. 114. Reverse proxy Web Server Symfony2 app Requests Response
  115. 115. Extensibility
  116. 116. Request core.request getController() core.controller getArguments() core.view core.response Response
  117. 117. Request core.request getController() core.controller core.exception getArguments() core.view core.response Response
  118. 118. SwiftmailerBundle DoctrineBundle ZendBundle ... FrameworkBundle TwigBundle Bundles Components HttpKernel DependencyInjection Console Routing Templating HttpFoundation Event Dispatcher ...
  119. 119. Questions?
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×