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

[Oslo and Helsinki meetups] Status about Symfony

[Oslo and Helsinki meetups] Status about Symfony

This presentation has been done for those meetups:
- Ez publish meetup in Oslo, Norway (http://www.meetup.com/eZ-Oslo-Meetup/events/222305799/)
- PHP meetup in Helsinki, Finland (http://www.meetup.com/Helsinki-Symfony-Meetup/events/222295052/)

Sarah KHALIL

June 05, 2015
Tweet

More Decks by Sarah KHALIL

Other Decks in Technology

Transcript

  1. WHO AM I? • Head of • Trainer & Developer

    • Enjoying sharer • Contributor to
  2. 3

  3. 5

  4. 7

  5. 8

  6. Dependency Injection BrowserKit ClassLoader Config CssSelector Debug DomCrawler Filesystem Finder

    HttpFoundation HttpKernel Locale Intl Icu OptionsResolver Process PropertyAccess Serializer Stopwatch Templating Translation Validator ExpressionLanguage Console yaml EventDispatcher Routing Security Form
  7. # 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);
  8. 30 Separation of Concerns Implementation Controller View Model Modifies the

    model Returns model data Renders the view The Controller analyses the user request, calls the Model and passes data to the View. The View layer formats data in a dedicated format (html, json…) The Model stores the business logic and classes that manipulate data. R Router Response Request /hello/fabien
  9. 30 Separation of Concerns Implementation Controller View Model Modifies the

    model Returns model data Renders the view The Controller analyses the user request, calls the Model and passes data to the View. The View layer formats data in a dedicated format (html, json…) The Model stores the business logic and classes that manipulate data. R Router Response Request /hello/fabien
  10. 30 Separation of Concerns Implementation Controller View Model Modifies the

    model Returns model data Renders the view The Controller analyses the user request, calls the Model and passes data to the View. The View layer formats data in a dedicated format (html, json…) The Model stores the business logic and classes that manipulate data. R Router Response Request /hello/fabien
  11. class DefaultController extends Controller { /** @Route("/hello/{name}") */ public function

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

    function indexAction() { return [ 'title' => 'Schedule' ]; } }
  13. {% 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 %}
  14. {% 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 %} index.html.twig
  15. {% extends "::base.html.twig" %} {% block body %} <img src="/images/logo.gif"

    /> {% block content '' %} {% endblock %} layout.html.twig
  16. <!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> base.html.twig
  17. Twig is a modern template engine for PHP ▪ Fast

    ▪ Concise and rich syntax ▪ Automatic output escaping ▪ Modern features ▪ Extensible
  18. Twig is a modern template engine for PHP ▪ Fast

    ▪ Concise and rich syntax ▪ Automatic output escaping ▪ Modern features ▪ Extensible twig.sensiolabs.org
  19. The router maps a url pattern to a set of

    internal parameters. It’s about matching a request to a callable => action
  20. /** * @Route( * "/{year}/talk/{month}/{day}/{slug}", * requirements={ * "year"="\d{4}", *

    "month"="\d{2}", * "day"="\d{2}" * } * ) */ public function showAction($slug, $day, $month, $year) { // ... }
  21. 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
  22. <?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
  23. ▪ Database Abstraction Layer on top of PDO ▪ Object

    Relational Mapper ▪ Migrations support ▪ Object Document Mapper (MongoDB) Doctrine2 Support
  24. /** @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; }
  25. <?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
  26. 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
  27. /** @Assert\UniqueEntity("username") */ class User { /** * @Assert\NotBlank *

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

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

    function indexAction() { return [ 'title' => 'Schedule' ]; } }
  32. <?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>
  33. {% set message = 'Symfony2 is great' %} {{ message|trans

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

    to perform an action... } Using annotations to secure an action authorization
  35. 100

  36. 100

  37. 3.0

  38. What  is  it  going  to  be? • Compared to 2.x?

    => No new feature • Removal of descending compatibility layer • Keeping the compatibility when possible • >= PHP 5.5.9
  39. Symfony  2.8  LTS? • Last refactoring of the 2.X branch

    • Last deprecations • New features • It will be the 3.0 + descending layers of compatibility • >= PHP 5.3.9
  40. How  to  handle  the  migration? • UPGRADE.md • Do not

    ignore the deprecation notices • grep/ack ;) • PHPStorm • • error_reporting(E_ALL–E_USER_DEPRECATED) https://knpuniversity.com/blog/upgrading-­‐symfony-­‐2.7
  41. Deprecated  constants • UuidValidator::STRICT_PATTERN   • UuidValidator::LOOSE_PATTERN   • UuidValidator::STRICT_UUID_LENGTH

      • FormEvents::BIND   • FormEvents::PRE_BIND   • FormEvents::POST_BIND   • Unescaper::ENCODING
  42. Twig  templates • Removal  of  the  {% render %} tag

      • Removal  of  the  {% include %} tag   • Removal  of  the  global  variable  `app.security`
  43. ClassLoader • Removal  of  the  ApcUniversalClassLoader • Removal  of  the

     DebugClassLoader  (use  the  Debug’s  one)   • Removal  of  the  DebugUniversalClassLoader • Removal  of  the  UniversalClassLoader  (use  Composer)
  44. Dependency  Injection  Component • No  more  «  scopes  ».  

    • «  synchronized  »  services  disappear.   • «  factory-­‐*  »  attributes  become  «  factory  »  tags.
  45. Console • DialogHelper  replaced  by  Question   • ProgressBarHelper  replaced

     by  ProgressBar   • TableHelper  replaced  by  Table   • Removal  of  the  Application::asText()  and::asXml()   • Removal  of  the  Command::asText()  and  ::asXml()   • Removal  of  the  InputDefinition::asText()  and  ::asXml()
  46. Event  Dispatcher • Removal  of  methods   • Event::setName()  

    • Event::getName()   • Event::getDispatcher()   • Event::setDispatcher()
  47. HTTP  Kernel • Removal  of  the  leagcy  LoggerInterface • Kernel::init()

    disappears  for  the  __construct() • HttpCache::getEsi()replaced  by   HttpCache::getSurrogate()
  48. Form  component • Form::bind()  -­‐>  Form::submit()  /  Form::handleRequest()   •

    No  more  Form::isBound()  neither  Form::getErrorsAsString()   • AbstractType::setDefaultOptions()   -­‐>  AbstractType::configureOptions()   • AbstractTypeExtension::setDefaultOptions()   -­‐>  AbstractTypeExtension::configureOptions()   • No  more  of  the  «  virtual  »  option
  49. 119

  50. 119

  51. Security • security.context  service  disappears   • Use  the  security.token_storage


                             &  security.authorization_checker • Removal  of  the  app.security  in  Twig          -­‐>  use  is_granted()
  52. Serializer • Removal  of  the  JsonDecode::getLastError()   • Removal  of

     the  JsonEncode::getLastError()   • Removal  of  the  JsonEncoder::getLastError()
  53. Validator • ViolationBuilder  /  ExecutionContext   -­‐>  addViolation()  replaced  by

     buildViolation().   • API  BC  (use  of  the  2.5  version).   • Function  Twig  form_enctype()  disappears.   • No  more  «  type  »  option  in  the  ISBN  constraint.   • No  more  «  methods  »  option  in  the  Callback  constraint.   • No  more  «  deep  »  option    in  the  Valid  constraint.   • The  constraints  Optional  &  Required  disappear.
  54. 126

  55. 126

  56. 129

  57. 130

  58. 131

  59. 132

  60. 132