Build smart and powerful web
 applications with Symfony2
Built around standalone and
 decoupled components…
… and a full-stack framework based
     on those components
Application bundles                  Third party bundles


                    The Symfony2 stack

     Core Bundles                       Third party libraries


                    Standalone Components
« A Bundle is a directory that has a well-de ned
structure and can host anything from classes to
       controllers and web resources.  »
What makes Symfony2 unique?
Symfony2 follows standards
     & best practices

      -  RFC2616
      -  PHPUnit
   -  Jinja Templates
   -  Design Patterns
Symfony is now easier
 to install and con gure

http://symfony.com/download
Several distributions available
      Download the Standard Edition that hosts the
      framework, standard bundles and a default application
      architecture.
Easy installation and con guration
Web con guration

Con gure the database access parameters
Start to use Symfony2 and happy coding J
Want to give it a try?
Symfony2 Philosophy



    « Basically, Symfony2 asks you to
   convert a Request into a Response »
Request handling

  class DefaultController extends Controller
  {
      /**
        * @extra:Route("/hello/{name}")
        */
      public function indexAction($name)
      {
           // ... do things

          return new Response(sprintf('Hello %s!', $name));
      }
  }
Request handling

 class DefaultController extends Controller
 {
     /**
       * @extra:Route("/hello/{name}")
       */
     public function indexAction($name)
     {
          // ... do things

         return $this->render('HelloBundle:Default:index.html.twig',
 array('name' => $name));
     }
 }
Request handling

    class DefaultController extends Controller
    {
        /**
          * @extra:Route("/schedule")
          * @extra:Template
          */
        public function indexAction()
        {
             $title = 'Confoo 2011 Conferences Schedule';

            return array('title' => $title);
        }
    }
Templating
{% extends "ConfooConferenceBundle::layout.html.twig" %}

{% block content %}

    <h1> {{ title }} </h1>

    <ul>
        <li>Caching on the Edge, by Fabien Potencier</li>
        <li>HipHop for PHP, by Scott Mac Vicar</li>
        <li>XDebug, by Derick Rethans</li>
        <li>...</li>
    </ul>

{% endblock %}
TWIG Template Engine
Twig is a modern template engine for PHP

       §  Fast
       §  Concise and rich syntax
       §  Automatic output escaping
       §  Modern features
       §  Extensible
       §  Flexible
Template inheritance
{% extends "ConfooConferenceBundle::layout.html.twig" %}

{% block content %}

    <h1> {{ title }} </h1>

    <ul>
        <li>Caching on the Edge, by Fabien Potencier</li>
        <li>HipHop for PHP, by Scott Mac Vicar</li>
        <li>XDebug, by Derick Rethans</li>
        <li>...</li>
    </ul>

{% endblock %}
Template inheritance

{% extends "::base.html.twig"   %}

{% block body %}

    <img src="/images/logo.gif" alt="Confoo 2011"/>

    {% block content %}{% endblock %}

{% endblock %}
Template inheritance

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type"
            content="text/html; charset=utf-8" />

        <title>{% block title %}Welcome!{% endblock %}</title>

        <link rel="shortcut icon" href="{{ asset('favicon.ico') }}" />
    </head>
    <body>
        {% block body %}{% endblock %}
    </body>
</html>
Template inheritance

 base.html.twig
                              layout.html.twig




                       index.html.twig
Smart URIs
Smart URIs




             Typical PHP URIs suck!!!
Smart URIs




        Native routing mechanism
Smart URIs
 class DefaultController extends Controller
 {
     /**
       * @extra:Route("/{year}/talk/{month}/{day}/{slug}")
       * @extra:Template
       */
     public function showAction($slug, $day, $month, $year)
     {
          // Get a talk object from the database
          $talk = ...;

         return array('talk' => $talk);
     }
 }
Parameter converter

 class DefaultController extends Controller
 {
     /**
       * @extra:Route("/talk/{id}")
       * @extra:Template
       */
     public function showAction(Talk $talk)
     {
          return array('talk' => $talk);
     }
 }
Easy Debugging
The Web Debug Toolbar




Symfony2 version environment environment
            PHP          Current           Current response RecordedTimers Memory
                                                                     logs     Queries
Exception stack traces
Exception stack traces
Recorded logs
The Pro ler application
The Pro ler application
Database Management
Doctrine 2 Library

 §  Database Abstraction Layer on top of PDO
 §  Object Relational Mapper
 §  Migrations support
 §  Object Document Mapper (MongoDB)
 §  Object XML Mapper (XML databases)
De ning entities as POPO
/**	
  * @orm:Entity	
  */	
class Talk	
{	
      /**	
       * @orm:Id	
       * @orm:GeneratedValue	
       * @orm:Column(type="integer")	
       */	
      public $id;	
	
      /** @orm:Column(length=80, nullable=false) */	
      public $title;	
	
      /** @orm:Column(type="text") */	
      public $synopsis;	
	
      /** @orm:Column(type="datetime") */	
      public $schedule;	
	
      /** @orm:ManyToMany(targetEntity="Speaker", mappedBy="talks") */	
      public $speakers;	
}
Validation
Validation


   §  Validate POPOs (properties & methods)

   §  Easy con guration with annotations

   §  Easy to customize and extend
Validating Plain PHP Objects

        class ContactRequest
        {
            /** @validation:NotBlank */
            public $message;

                /**
                 * @validation:Email
                 * @validation:NotBlank
                 */
                public $sender;
            }
        }
Forms Handling
Forms management

§  Transparent layer on top of your domain object

§  Native CSRF protection

§  Coupled to the Validation framework

§  Twig integration
Designing a basic form class

     namespace ConfooContactBundleForm;

     use   SymfonyComponentFormForm;
     use   SymfonyComponentFormTextField;
     use   SymfonyComponentFormTextareaField;
     use   SymfonyComponentFormCheckboxField;

     class ContactForm extends Form
     {
         protected function configure()
         {
             $this->add(new TextField('sender')));
             $this->add(new TextareaField('message'));
         }
     }
Processing a form
   public function contactAction()
   {
       $contactRequest = new ContactRequest();

       $form = ContactForm::create(...);

       $form->bind($this->get('request'), $contactRequest);

       if ($form->isValid()) {

           // do things with validated data
       }

       return array('form' => $form);
   }
Prototyping the rendering with Twig

 {% extends 'ConfooContactBundle::layout.html.twig' %}

 {% block content %}

 <form action="#" method="post">

    {{ form_field(form) }}

    <input type="submit" value="Send!" />

 </form>

 {% endblock %}
Functional Testing
Functional testing



     Simulating an end-user browsing
     scenario and testing the Response
Functional Testing

class DefaultControllerTest extends WebTestCase
{
    public function testIndex()
    {
        $client = $this->createClient();

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

        $this->assertTrue(
            $crawler->filter('html:contains("Fabien Potencier")')->count() > 0
        );

        $this->assertTrue($client->getResponse()->headers->has('expires'));
    }
}
HTTP Compliance (RFC2616)
Expiration / Validation
Expiration with Expires

    class DefaultController extends Controller
    {
        /**
          * @extra:Route("/schedule")
          * @extra:Template
          * @extra:Cache(expires="tomorrow")
          */
        public function indexAction()
        {
             $title = 'Confoo 2011 Conferences Schedule';

            return array('title' => $title);
        }
    }
Expiration with Cache-Control

    class DefaultController extends Controller
    {
        /**
          * @extra:Route("/schedule")
          * @extra:Template
          * @extra:Cache(maxage="20", s-maxage="20")
          */
        public function indexAction()
        {
             $title = 'Confoo 2011 Conferences Schedule';

            return array('title' => $title);
        }
    }
Native PHP Reverse Proxy Cache
Varnish / Squid
Edge Side Includes

<esi:include src="http://..." />
Security
Authentication & Authorization
Thank You!

Build powerfull and smart web applications with Symfony2

  • 1.
    Build smart andpowerful web applications with Symfony2
  • 3.
    Built around standaloneand decoupled components…
  • 4.
    … and afull-stack framework based on those components
  • 5.
    Application bundles Third party bundles The Symfony2 stack Core Bundles Third party libraries Standalone Components
  • 6.
    « A Bundle isa directory that has a well-de ned structure and can host anything from classes to controllers and web resources.  »
  • 7.
  • 8.
    Symfony2 follows standards & best practices -  RFC2616 -  PHPUnit -  Jinja Templates -  Design Patterns
  • 9.
    Symfony is noweasier to install and con gure http://symfony.com/download
  • 10.
    Several distributions available Download the Standard Edition that hosts the framework, standard bundles and a default application architecture.
  • 11.
  • 12.
    Web con guration Congure the database access parameters
  • 13.
    Start to useSymfony2 and happy coding J
  • 14.
    Want to giveit a try?
  • 15.
    Symfony2 Philosophy « Basically, Symfony2 asks you to convert a Request into a Response »
  • 16.
    Request handling class DefaultController extends Controller { /** * @extra:Route("/hello/{name}") */ public function indexAction($name) { // ... do things return new Response(sprintf('Hello %s!', $name)); } }
  • 17.
    Request handling classDefaultController extends Controller { /** * @extra:Route("/hello/{name}") */ public function indexAction($name) { // ... do things return $this->render('HelloBundle:Default:index.html.twig', array('name' => $name)); } }
  • 18.
    Request handling class DefaultController extends Controller { /** * @extra:Route("/schedule") * @extra:Template */ public function indexAction() { $title = 'Confoo 2011 Conferences Schedule'; return array('title' => $title); } }
  • 19.
    Templating {% extends "ConfooConferenceBundle::layout.html.twig"%} {% block content %} <h1> {{ title }} </h1> <ul> <li>Caching on the Edge, by Fabien Potencier</li> <li>HipHop for PHP, by Scott Mac Vicar</li> <li>XDebug, by Derick Rethans</li> <li>...</li> </ul> {% endblock %}
  • 20.
    TWIG Template Engine Twigis a modern template engine for PHP §  Fast §  Concise and rich syntax §  Automatic output escaping §  Modern features §  Extensible §  Flexible
  • 21.
    Template inheritance {% extends"ConfooConferenceBundle::layout.html.twig" %} {% block content %} <h1> {{ title }} </h1> <ul> <li>Caching on the Edge, by Fabien Potencier</li> <li>HipHop for PHP, by Scott Mac Vicar</li> <li>XDebug, by Derick Rethans</li> <li>...</li> </ul> {% endblock %}
  • 22.
    Template inheritance {% extends"::base.html.twig" %} {% block body %} <img src="/images/logo.gif" alt="Confoo 2011"/> {% block content %}{% endblock %} {% endblock %}
  • 23.
    Template inheritance <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>{% block title %}Welcome!{% endblock %}</title> <link rel="shortcut icon" href="{{ asset('favicon.ico') }}" /> </head> <body> {% block body %}{% endblock %} </body> </html>
  • 24.
    Template inheritance base.html.twig layout.html.twig index.html.twig
  • 25.
  • 26.
    Smart URIs Typical PHP URIs suck!!!
  • 27.
    Smart URIs Native routing mechanism
  • 28.
    Smart URIs classDefaultController extends Controller { /** * @extra:Route("/{year}/talk/{month}/{day}/{slug}") * @extra:Template */ public function showAction($slug, $day, $month, $year) { // Get a talk object from the database $talk = ...; return array('talk' => $talk); } }
  • 29.
    Parameter converter classDefaultController extends Controller { /** * @extra:Route("/talk/{id}") * @extra:Template */ public function showAction(Talk $talk) { return array('talk' => $talk); } }
  • 30.
  • 31.
    The Web DebugToolbar Symfony2 version environment environment PHP Current Current response RecordedTimers Memory logs Queries
  • 32.
  • 33.
  • 34.
  • 35.
    The Pro lerapplication
  • 36.
    The Pro lerapplication
  • 37.
  • 38.
    Doctrine 2 Library §  Database Abstraction Layer on top of PDO §  Object Relational Mapper §  Migrations support §  Object Document Mapper (MongoDB) §  Object XML Mapper (XML databases)
  • 39.
    De ning entitiesas POPO /** * @orm:Entity */ class Talk { /** * @orm:Id * @orm:GeneratedValue * @orm:Column(type="integer") */ public $id; /** @orm:Column(length=80, nullable=false) */ public $title; /** @orm:Column(type="text") */ public $synopsis; /** @orm:Column(type="datetime") */ public $schedule; /** @orm:ManyToMany(targetEntity="Speaker", mappedBy="talks") */ public $speakers; }
  • 40.
  • 41.
    Validation §  Validate POPOs (properties & methods) §  Easy con guration with annotations §  Easy to customize and extend
  • 42.
    Validating Plain PHPObjects class ContactRequest { /** @validation:NotBlank */ public $message; /** * @validation:Email * @validation:NotBlank */ public $sender; } }
  • 43.
  • 44.
    Forms management §  Transparentlayer on top of your domain object §  Native CSRF protection §  Coupled to the Validation framework §  Twig integration
  • 45.
    Designing a basicform class namespace ConfooContactBundleForm; use SymfonyComponentFormForm; use SymfonyComponentFormTextField; use SymfonyComponentFormTextareaField; use SymfonyComponentFormCheckboxField; class ContactForm extends Form { protected function configure() { $this->add(new TextField('sender'))); $this->add(new TextareaField('message')); } }
  • 46.
    Processing a form public function contactAction() { $contactRequest = new ContactRequest(); $form = ContactForm::create(...); $form->bind($this->get('request'), $contactRequest); if ($form->isValid()) { // do things with validated data } return array('form' => $form); }
  • 47.
    Prototyping the renderingwith Twig {% extends 'ConfooContactBundle::layout.html.twig' %} {% block content %} <form action="#" method="post"> {{ form_field(form) }} <input type="submit" value="Send!" /> </form> {% endblock %}
  • 48.
  • 49.
    Functional testing Simulating an end-user browsing scenario and testing the Response
  • 50.
    Functional Testing class DefaultControllerTestextends WebTestCase { public function testIndex() { $client = $this->createClient(); $crawler = $client->request('GET', '/schedule'); $this->assertTrue( $crawler->filter('html:contains("Fabien Potencier")')->count() > 0 ); $this->assertTrue($client->getResponse()->headers->has('expires')); } }
  • 51.
  • 52.
  • 53.
    Expiration with Expires class DefaultController extends Controller { /** * @extra:Route("/schedule") * @extra:Template * @extra:Cache(expires="tomorrow") */ public function indexAction() { $title = 'Confoo 2011 Conferences Schedule'; return array('title' => $title); } }
  • 54.
    Expiration with Cache-Control class DefaultController extends Controller { /** * @extra:Route("/schedule") * @extra:Template * @extra:Cache(maxage="20", s-maxage="20") */ public function indexAction() { $title = 'Confoo 2011 Conferences Schedule'; return array('title' => $title); } }
  • 55.
    Native PHP ReverseProxy Cache
  • 56.
  • 57.
  • 58.
  • 59.