Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Web Development with Symfony

Web Development with Symfony

Hugo Hamon

May 08, 2014
Tweet

More Decks by Hugo Hamon

Other Decks in Technology

Transcript

  1. Web Development with
    Symfony Friday May 9th 2014 – Osijek – Croatia

    View full-size slide

  2. Hugo HAMON
    Head of training at SensioLabs
    Book author
    Speaker at Conferences
    Symfony contributor
    @hhamon

    View full-size slide

  3. What is
    Symfony2

    View full-size slide

  4. Framework
    Philosophy
    Community

    View full-size slide

  5. Symfony2 is a set of reusable,
    standalone, decoupled, and
    cohesive PHP components that
    solve common web development
    problems.

    View full-size slide

  6. Dependency Injection
    BrowserKit
    ClassLoader
    Config
    Console CssSelector Debug
    DomCrawler
    EventDispatcher
    ExpressionLanguage Filesystem
    Finder Form
    HttpFoundation
    HttpKernel
    Locale Intl Icu
    OptionsResolver
    Process
    PropertyAccess
    Routing Security
    Serializer Stopwatch Templating Translation
    Validator
    Yaml

    View full-size slide

  7. Symfony is also a full stack
    web framework made of
    bundles and third party
    libraries.

    View full-size slide

  8. +1,000 code contributors

    View full-size slide

  9. +700 documentation contributors

    View full-size slide

  10. +2,200 community bundles

    View full-size slide

  11. And many open source projects!

    View full-size slide

  12. IDE Integration

    View full-size slide

  13. Installation

    View full-size slide

  14. Easy installation

    View full-size slide

  15. Easy installation with Composer

    View full-size slide

  16. The First Page

    View full-size slide

  17. Configuration

    View full-size slide

  18. # web/app.php
    use Symfony\Component\HttpFoundation\Request;
    $kernel = new AppKernel('prod', false);
    $kernel->loadClassCache();
    $request = Request::createFromGlobals();
    $response = $kernel->handle($request);
    $response->send();
    $kernel->terminate($request, $response);

    View full-size slide

  19. namespace Acme\DemoBundle\Controller;
    use Sensio\Bundle\FrameworkExtraBundle\[…]\Route;
    use Symfony\Component\HttpFoundation\Response;
    class DefaultController
    {
    /** @Route("/hello/{name}") */
    public function indexAction($name)
    {
    return new Response('Hello '.$name);
    }
    }

    View full-size slide

  20. class DefaultController extends Controller
    {
    /** @Route("/hello/{name}") */
    public function indexAction($name)
    {
    return $this->render(
    'AcmeDemoBundle:Default:index.html.twig',
    [ 'name' => $name ]
    );
    }
    }

    View full-size slide

  21. class DefaultController
    {
    /**
    * @Route("/schedule")
    * @Template
    */
    public function indexAction()
    {
    return [ 'title' => 'Schedule' ];
    }
    }

    View full-size slide

  22. {% extends "SensioConferenceBundle::layout.html.twig" %}
    {% block content %}
    {{ title }}

    HTTP Caching, by Fabien Potencier
    HipHop for PHP, by Scott Mac Vicar
    XDebug, by Derick Rethans
    ...

    {% endblock %}

    View full-size slide

  23. Twig is a modern template engine for PHP
    §  Fast
    §  Concise and rich syntax
    §  Automatic output escaping
    §  Modern features
    §  Extensible
    §  Flexible

    View full-size slide

  24. {% extends "SensioConferenceBundle::layout.html.twig" %}
    {% block title 'Conference Schedule' %}
    {% block content %}
    {{ title }}

    HTTP Caching, by Fabien Potencier
    HipHop for PHP, by Scott Mac Vicar
    XDebug, by Derick Rethans
    ...

    {% endblock %}

    View full-size slide

  25. {% extends "::base.html.twig" %}
    {% block body %}

    {% block content '' %}
    {% endblock %}

    View full-size slide





  26. {% block title 'Welcome!' %}



    {% block body '' %}


    View full-size slide

  27. layout.html.twig
    index.html.twig
    base.html.twig

    View full-size slide

  28. Development
    Tools

    View full-size slide

  29. Code Generators

    View full-size slide

  30. $ php app/console generate:bundle

    View full-size slide

  31. $ php app/console generate:doctrine:crud

    View full-size slide

  32. Routing System

    View full-size slide

  33. The router maps a url
    pattern to a set of internal
    parameters.

    View full-size slide

  34. /**
    * @Route(
    * "/{year}/talk/{month}/{day}/{slug}",
    * requirements={
    * "year"="\d{4}",
    * "month"="\d{2}",
    * "day"="\d{2}"
    * }
    * )
    */
    public function showAction($slug, $day, $month, $year)
    {
    // ...
    }

    View full-size slide

  35. acme_blog_show:
    path: /{year}/talk/{month}/{day}/{slug}
    defaults: { _controller: AcmeBlogBundle:Blog:blog }
    requirements:
    year: "\d{4}"
    month: "\d{2}"
    day: "\d{2}"
    schemes: https
    methods: GET
    host: blog.my-domain.com
    condition: "request.headers.get('User-Agent') matches '/firefox/i'"
    YAML Configuration

    View full-size slide



  36. path="/{year}/talk/{month}/{day}/{slug}"
    schemes="https"
    method="GET"
    >
    AcmeBlogBundle:Blog:show
    \d{4}
    \d{2}
    \d{2}
    request.headers.get('User-Agent') matches '/firefox/i'


    XML Configuration

    View full-size slide

  37. /** @Route("/talk/{id}") */
    function showAction(Talk $talk)
    {
    // ...
    }
    Automatic Arguments Discovery

    View full-size slide

  38. Database
    Handling

    View full-size slide

  39. h"p://www.flickr.com/photos/chanceprojects/  

    View full-size slide

  40. § Database Abstraction Layer on top of PDO
    § Object Relational Mapper
    § Migrations support
    § Object Document Mapper (MongoDB)
    § Object XML Mapper (XML databases)
    Doctrine2 Support

    View full-size slide

  41. /** @ORM\Entity */
    class Talk
    {
    /**
    * @ORM\Id
    * @ORM\GeneratedValue
    * @ORM\Column(type="integer")
    */
    private $id;
    /** @ORM\Column(length=80) */
    private $title;
    /** @ORM\Column(type="text") */
    private $synopsis;
    /** @ORM\Column(type="datetime") */
    private $schedule;
    /** @ORM\ManyToMany(targetEntity="Speaker", mappedBy="talks") */
    private $speakers;
    }

    View full-size slide

  42. Service
    Container

    View full-size slide

  43. The service container
    centralizes the intelligence
    to create and initialize
    objects.

    View full-size slide

  44. services:
    user_manager:
    class: Acme\UserManager
    arguments:
    - "@event_dispatcher"
    - "@security.encoder_factory"
    - "@doctrine.orm.entity_manager"
    - "@security.context"
    YAML Configuration

    View full-size slide












  45. XML Configuration

    View full-size slide

  46. class appProdProjectContainer extends Container
    {
    protected function getUserManagerService()
    {
    $instance = new Acme\UserManager(
    $this->get('debug.event_dispatcher'),
    $this->get('security.encoder_factory'),
    $this->get('doctrine.orm.default_entity_manager'),
    $this->get('security.context')
    );
    $this->services['user_manager'] = $instance;
    return $instance;
    }
    }
    Service Factory Method

    View full-size slide

  47. $manager = $this
    ->container
    ->get('user_manager')
    ;
    Service Lazy Loading

    View full-size slide

  48. Data
    Validation

    View full-size slide

  49. The validator component
    validates objects againsts a
    set of constraints.

    View full-size slide

  50. /** @Assert\UniqueEntity("username") */
    class User
    {
    /**
    * @Assert\NotBlank
    * @Assert\Email
    */
    private $username;
    /**
    * @Assert\NotBlank
    * @Assert\Length(min = 8, max = 32)
    */
    private $password;
    // ...
    }

    View full-size slide

  51. $user = new User();
    $user->setUsername('[email protected]');
    $user->setPassword('changeme');
    $validator = $this->get('validator');
    $errors = $validator->validate($user);
    Validating an Object

    View full-size slide

  52. Forms
    management

    View full-size slide

  53. h"p://www.flickr.com/photos/miahz/  

    View full-size slide

  54. namespace Sensio\UserBundle\Form;
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    class UserType extends AbstractType
    {
    function buildForm(FormBuilderInterface $builder, …)
    {
    $builder
    ->add('username', 'email')
    ->add('password', 'password')
    ->add('submit', 'submit')
    ;
    }
    }

    View full-size slide

  55. public function userAction(Request $request)
    {
    $user = new User();
    $user->setUsername('[email protected]');
    $form = $this->createForm(new UserType(), $user);
    $form->handleRequest($request);
    if ($form->isValid()) {
    // ...
    }
    return ['form' => $form->createView() ];
    }

    View full-size slide

  56. {{ form(form) }}
    Displaying the form

    View full-size slide

  57. Automated
    Tests

    View full-size slide

  58. h"p://www.flickr.com/photos/kenstein/  

    View full-size slide

  59. UNIT TESTING

    View full-size slide

  60. FUNCTIONAL TESTING

    View full-size slide

  61. Expiration
    Validation

    View full-size slide

  62. class DefaultController
    {
    /**
    * @Template
    * @Cache(expires="tomorrow")
    */
    public function indexAction()
    {
    return [ 'title' => 'Schedule' ];
    }
    }

    View full-size slide

  63. class DefaultController
    {
    /**
    * @Template
    * @Cache(maxage=120)
    */
    public function indexAction()
    {
    return [ 'title' => 'Schedule' ];
    }
    }

    View full-size slide

  64. HTTP Reverse
    Proxy Caching

    View full-size slide

  65. varnish-cache.org

    View full-size slide

  66. Edge Side Includes

    View full-size slide

  67. Internationalization
    Localization

    View full-size slide

  68. h"p://www.flickr.com/photos/bwop/  

    View full-size slide






  69. Symfony2 is great
    J'aime Symfony2




    View full-size slide

  70. {% set message = 'Symfony2 is great' %}
    {{ message|trans }}
    {% set message = 'My name is %name%!' %}
    {{ message|trans({'%name%': 'Hugo'}, "hello") }}

    View full-size slide

  71. Authentication
    Authorizations

    View full-size slide

  72. h"p://www.flickr.com/photos/cstein96/  

    View full-size slide

  73. /**
    * @Security("has_role('ROLE_ADMIN')")
    */
    public function editAction($id)
    {
    // granted to perform an action...
    }
    Using annotations to secure an action

    View full-size slide

  74. Using expression to secure an action
    /**
    * @Security(
    * expression="is_granted('EDIT', article)"
    * )
    */
    public function editAction(Article $article)
    {
    // granted to perform an action...
    }

    View full-size slide

  75. Questions?
    h"p://www.flickr.com/photos/mkrigsman/  

    View full-size slide