State of the Symfony World

State of the Symfony World

SymfonyLive Berlin 2013

9a22d09f92d50fa3d2a16766d0ba52f8?s=128

Fabien Potencier

November 09, 2013
Tweet

Transcript

  1. State of the Symfony World FabienPotencier fabpot h﬙ps:/ /secure.flickr.com/photos/abufaiqa/4408154571

  2. Twig 1.7M downloads

  3. 1.5M downloads

  4. ~21M downloads

  5. Console Event Dispatcher Finder HTTP Foundation HTTP Kernel Yaml Process

    Routing Translation Dom Crawler Filesystem CSS Selector Browser Kit ICU Debug
  6. easybook Sulu CMF

  7. The Symfony Family https://secure.flickr.com/photos/65073487@N00/3132301417

  8. h﬙p:/ /symfony.com/components

  9. h﬙p:/ /symfony.com/components/H﬙pKernel

  10. h﬙p:/ /symfony.com/projects

  11. h﬙p:/ /symfony.com/projects/phpbb

  12. Add your project to the SymfonyFamily today! h﬙ps:/ /github.com/symfony/symfony-marketing/tree/component/projects 40+

    projects https://secure.flickr.com/photos/kismihok/2894418909
  13. 2.4 1200+ commits

  14. h﬙p:/ /symfony.com/roadmap

  15. 2.4 30+ new/improved features

  16. Form Panel in the Web Profiler Limiting Session Metadata Writes

    Quicker Access to the Profiler when working on an API A more powerful image validator Flushing stdout and stderr on a Process Easier debugging of not-found resources Using Constants for HTTP Status Code Disabling internal Validation of DomCrawler ChoiceFormFields Dumping the default Configuration for an Extension Be﬙er Console Integration with third-par﬚ Tools Namespaces auto-discovery in DowCrawler A be﬙er Callback constraint Console improvements Restrict Securi﬚ Firewalls to specific Hosts Limit a Process Run with an idle Timeout A Stopwatch Tag for Twig Be﬙er Error Messages for missing Classes and Functions Show logs in console Customize the Securi﬚ Features with ease h﬙p:/ /symfony.com/blog/category/living-on-the-edge
  17. None
  18. 2.4 2 big features

  19. 2.4 Expression Language Request Stack

  20. Expression Language https://secure.flickr.com/photos/sergiu_bacioiu/3930657923

  21. foo.bar foo.getBar() foo['bar']

  22. $language = new ExpressionLanguage(); echo $language->evaluate('1 + 1'); // will

    echo 2 echo $language->compile('1 + 2'); // will echo "(1 + 2)"
  23. not foo or bar foo in ['foo', 'bar'] foo ?

    true : false foo matches "/^foo/i"
  24. http://www.flickr.com/photos/doug88888/4561376850

  25. class Foo { public function __construct($locale) { $this->locale = $locale;

    } }
  26. acme.locale: class: Symfony\Component\HttpFoundation\Request factory_service: request factory_method: getLocale

  27. $c->register('foo', 'Foo')->addArgument( new Expression('container.get("request").getLocale()') ); <service id="foo" class="Foo"> <argument type="expression">

    container.get("request").getLocale() </argument> </service>
  28. $c->register('foo', 'Foo')->addArgument( new Expression('service("request").getLocale()') ); $c->register('foo', 'Foo')->addArgument( new Expression( 'service("request").getLocale(parameter("def_locale"))'

    ));
  29. $this->get("request")->getLocale( $this->getParameter("def_locale") )

  30. http://www.flickr.com/photos/21496790@N06/5065834411

  31. access_control: - path: ^/_internal roles: IS_AUTHENTICATED_ANONYMOUSLY ip: 127.0.0.1 - path:

    ^/_internal roles: ROLE_NO_ACCESS access_control: - path: ^/_internal roles: IS_AUTHENTICATED_ANONYMOUSLY ip: 127.0.0.1
  32. access_control: - path: ^/_internal/secure allow_if: "'127.0.0.1' == request.getClientIp()"

  33. '127.0.0.1' == request.getClientIp() or has_role('ROLE_ADMIN')

  34. /** * @Route("/post/{id}") * @Security("has_role('ROLE_ADMIN')") */ public function showAction(Post $post)

    { }
  35. /** * @Route("/post/{id}") * @Cache(smaxage="15") */ public function showAction(Request $request,

    Post $post) { $response = new Response(); $response->setLastModified($post->getUpdated()); if ($response->isNotModified($request)) { return $response; } // ... }
  36. /** * @Route("/post/{id}") * @Cache(smaxage="15", lastModified="post.getUpdatedAt()") */ public function showAction(Post

    $post) { // ... }
  37. http://www.flickr.com/photos/bootbearwdc/234526475

  38. hello: path: /hello/{name} condition: "request.getMethod() in ['GET', 'HEAD'] and request.headers.get('User-Agent')

    matches '/firefox/i'"
  39. // hello if ( 0 === strpos($pathinfo, '/hello') && preg_match('#^/hello/(?P<name>[^/]++)$#s',

    $pathinfo, $matches) && (in_array($context->getMethod(), array("GET", "HEAD")) && preg_match("/firefox/i", $request->headers- >get("User-Agent")))) { }
  40. http://www.flickr.com/photos/xfile001/5249936929

  41. /** * @Assert\Expression( * "value <= this.getMaxNumberOfLoginAttempts()", * message="Too many

    login attempts." * ) */ private $loginAttempts;
  42. # Get the special price if user.getGroup() in ['good_customers', 'collaborator']

    # Promote article to the homepage when article.commentCount > 100 and article.category not in ["misc"] # Send an alert when product.stock < 15
  43. The Request Stack https://secure.flickr.com/photos/kemped/3705729840

  44. What is a scope? What is a strict service? What

    is a synchronized service?
  45. Master Request {{ render(controller('a:b:c')) }} Sub-Request

  46. Request Response response Call Controller response? expection Sub-Request terminate controller

    view resolve controller resolve arguments request exception “sub-response” content
  47. Call Controller Request Response response response? expection Sub-Request terminate controller

    view resolve controller resolve arguments request exception “sub-response” content
  48. class FooService { public function __construct(Request $request) { $this->request =

    $request; } public function doSomething() { $this->request->...(); } }
  49. class FooService { public function __construct(ContainerInterface $container) { $this->container =

    $container; } public function doSomething() { $this->container->get('request')->...(); } }
  50. Inject the dependencies Not the Container Pro Tip #1

  51. Scopes Strict services Synchronized services

  52. None
  53. How can I depend on the Request in my services?

  54. use Symfony\Component\HttpFoundation\RequestStack; class FooService { public function __construct(RequestStack $requestStack) {

    $this->requestStack = $requestStack; } public function doSomething() { $this->requestStack->getCurrentRequest()->...(); } }
  55. $requestStack->getCurrentRequest()

  56. class FooController { public function indexAction(Request $request) { $request->...(); }

    } class FooListener { public function onKernelRequest(GetResponseEvent $event) { $event->getRequest()->...(); } }
  57. Inject the Request Stack Not the Request Pro Tip #2

  58. 3.0

  59. Silex 2.0 h﬙ps:/ /github.com/silexphp/Silex/tree/2.0-experimental

  60. SensioLabsInsight insight.sensiolabs.com

  61. h﬙p:/ /awards.symfony.com/

  62. None
  63. !ank y"!