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. Hugo HAMON Head of training at SensioLabs Book author Speaker

    at Conferences Symfony contributor @hhamon
  2. Symfony2 is a set of reusable, standalone, decoupled, and cohesive

    PHP components that solve common web development problems.
  3. 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
  4. Symfony is also a full stack web framework made of

    bundles and third party libraries.
  5. # 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);
  6. class DefaultController extends Controller { /** @Route("/hello/{name}") */ public function

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

    function indexAction() { return [ 'title' => 'Schedule' ]; } }
  8. {% extends "SensioConferenceBundle::layout.html.twig" %} {% block content %} <h1> {{

    title }} </h1> <ul> <li>HTTP Caching, by Fabien Potencier</li> <li>HipHop for PHP, by Scott Mac Vicar</li> <li>XDebug, by Derick Rethans</li> <li>...</li> </ul> {% endblock %}
  9. Twig is a modern template engine for PHP §  Fast

    §  Concise and rich syntax §  Automatic output escaping §  Modern features §  Extensible §  Flexible
  10. {% extends "SensioConferenceBundle::layout.html.twig" %} {% block title 'Conference Schedule' %}

    {% block content %} <h1> {{ title }} </h1> <ul> <li>HTTP Caching, by Fabien Potencier</li> <li>HipHop for PHP, by Scott Mac Vicar</li> <li>XDebug, by Derick Rethans</li> <li>...</li> </ul> {% endblock %}
  11. <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" ... /> <title>{% block

    title 'Welcome!' %}</title> <link … href="{{ asset('favicon.ico') }}" /> </head> <body> {% block body '' %} </body> </html>
  12. /** * @Route( * "/{year}/talk/{month}/{day}/{slug}", * requirements={ * "year"="\d{4}", *

    "month"="\d{2}", * "day"="\d{2}" * } * ) */ public function showAction($slug, $day, $month, $year) { // ... }
  13. 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
  14. <?xml version="1.0" encoding="UTF-8" ?> <routes> <route id="acme_blog_show" path="/{year}/talk/{month}/{day}/{slug}" schemes="https" method="GET"

    > <default key="_controller">AcmeBlogBundle:Blog:show</default> <requirement key="year">\d{4}</requirement> <requirement key="month">\d{2}</requirement> <requirement key="day">\d{2}</requirement> <condition>request.headers.get('User-Agent') matches '/firefox/i'<condition> </route> </routes> XML Configuration
  15. § Database Abstraction Layer on top of PDO § Object Relational Mapper

    § Migrations support § Object Document Mapper (MongoDB) § Object XML Mapper (XML databases) Doctrine2 Support
  16. /** @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; }
  17. <?xml version="1.0" ?> <container> <services> <service id="user_manager" class="Acme\UserManager"> <argument type="service"

    id="event_dispatcher"/> <argument type="service" id="security.encoder_factory"/> <argument type="service" id="doctrine.orm.entity_manager"/> <argument type="service" id="security.context" /> </service> </services> </container> XML Configuration
  18. 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
  19. /** @Assert\UniqueEntity("username") */ class User { /** * @Assert\NotBlank *

    @Assert\Email */ private $username; /** * @Assert\NotBlank * @Assert\Length(min = 8, max = 32) */ private $password; // ... }
  20. 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') ; } }
  21. 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() ]; }
  22. class DefaultController { /** * @Template * @Cache(expires="tomorrow") */ public

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

    function indexAction() { return [ 'title' => 'Schedule' ]; } }
  24. <?xml version="1.0"?> <xliff version="1.2"> <file …> <body> <trans-unit id="1"> <source>Symfony2

    is great</source> <target>J'aime Symfony2</target> </trans-unit> </body> </file> </xliff>
  25. {% set message = 'Symfony2 is great' %} {{ message|trans

    }} {% set message = 'My name is %name%!' %} {{ message|trans({'%name%': 'Hugo'}, "hello") }}
  26. /** * @Security("has_role('ROLE_ADMIN')") */ public function editAction($id) { // granted

    to perform an action... } Using annotations to secure an action
  27. Using expression to secure an action /** * @Security( *

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