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

The Wonderful World of Symfony Components

weaverryan
September 28, 2012

The Wonderful World of Symfony Components

Wow, Symfony Components!

In this talk, we'll look at the history of PHP, and the struggles as a community to create shared libraries between our large community. Find out the significance of PSR-0 and Composer in *your* life and how you can leverage libraries from all of PHP in your projects.

We'll also look at the most fundamental Symfony2 components - HttpFoundation, HttpKernel, EventDispatcher, & Routing - including those that have been adopted by Drupal 8. We'll also check out a bunch of the other interesting Symfony2 components that can be used as tools in any PHP project.

The goal of this talk is to show you just how easy finding and using high quality libraries has become in PHP. By the end, you'll be excited and ready to high-five all of your PHP friends.

weaverryan

September 28, 2012
Tweet

More Decks by weaverryan

Other Decks in Technology

Transcript

  1. The Wonderful World of the
    Symfony Components
    by your friend:
    Ryan Weaver
    @weaverryan
    Friday, September 28, 12

    View Slide

  2. Who is this dude?
    • That “Docs” guy
    • KnpLabs US - Symfony consulting, training, Kumbaya
    • Writer for KnpUniversity.com
    screencasts
    • Husband of the much more
    talented @leannapelham
    knplabs.com
    github.com/weaverryan
    @weaverryan
    Friday, September 28, 12

    View Slide

  3. Intro
    Life before components
    (The Desert of the Real)
    Friday, September 28, 12

    View Slide

  4. Symfony consists of 23
    individual components
    Friday, September 28, 12

    View Slide

  5. Components are available
    via Composer
    Friday, September 28, 12

    View Slide

  6. Snooze...
    Friday, September 28, 12

    View Slide

  7. Who Cares?
    Friday, September 28, 12

    View Slide

  8. We Suck at Sharing
    and that sucks for you
    @weaverryan
    1
    Friday, September 28, 12

    View Slide

  9. Including External Libraries
    is Depressing
    Friday, September 28, 12

    View Slide

  10. The Big Bummer :(
    @weaverryan
    • How do I autoload their files?
    • Does their library depend on anything else?
    • How do I even store their files in my project?
    Friday, September 28, 12

    View Slide

  11. Include a Zend Framework 1
    component in symfony1
    Friday, September 28, 12

    View Slide

  12. Friday, September 28, 12

    View Slide

  13. manually download the
    library and commit it
    into your project
    Friday, September 28, 12

    View Slide

  14. if you don’t want the
    WHOLE library, carefully
    delete everything except
    the dependent components
    Friday, September 28, 12

    View Slide

  15. autoloading is completely
    custom ... blah gross!
    Friday, September 28, 12

    View Slide

  16. Components are the key to
    mastering your framework
    @weaverryan
    2
    Friday, September 28, 12

    View Slide

  17. If PHP is big, we’ll thrive
    If PHP is small, we’ll die
    @weaverryan
    3
    Friday, September 28, 12

    View Slide

  18. Communities
    @weaverryan
    PHP is Huge! Right?
    http://www.flickr.com/photos/kitty-kat/
    Friday, September 28, 12

    View Slide

  19. @weaverryan
    PHP > Ruby
    Friday, September 28, 12

    View Slide

  20. Fragmentation
    @weaverryan
    But fragmentation makes us tiny, isolated, and
    misguided trend-setters
    http://www.flickr.com/photos/slpunk99/7329609744
    Friday, September 28, 12

    View Slide

  21. PHP frameworks < Rails
    @weaverryan
    Friday, September 28, 12

    View Slide

  22. I don’t want a damned
    CakePHP Plugin!
    @weaverryan
    CakePHP
    CodeIgniter
    Friday, September 28, 12

    View Slide

  23. Fragmentation
    @weaverryan
    • More information we have to know
    • Difficult to hire
    • Disjointed forums, StackOverflow
    • Interoperability? What’s that?
    Friday, September 28, 12

    View Slide

  24. Components are shareable
    across all of PHP
    Friday, September 28, 12

    View Slide

  25. Act 1
    Making Sharing Sexy
    Friday, September 28, 12

    View Slide

  26. PHP Framework
    Interoperability Group
    http://www.php-fig.org/
    Friday, September 28, 12

    View Slide

  27. The United Nations of PHP
    Friday, September 28, 12

    View Slide

  28. (A)
    The Problem of Autoloading
    Friday, September 28, 12

    View Slide

  29. My Autoloader doesn’t like
    your PHPs
    @weaverryan
    • The symfony1 autoloader doesn’t know where ZF1
    classes live. The Zf1 autoloader doesn’t know where
    symfony1 classes live
    • Each library has its own autoloader that you must
    discover, configure and use
    Friday, September 28, 12

    View Slide

  30. like a town where every
    store has its own currency
    Friday, September 28, 12

    View Slide

  31. From The Mountain:
    PSR-0 Class Naming Conventions
    @weaverryan
    “Thou shalt name your classes by
    following a predictable pattern”
    Friday, September 28, 12

    View Slide

  32. class:
    sfRequest
    path:
    lib/vendor/symfony/???idk
    Friday, September 28, 12

    View Slide

  33. class:
    Symfony\Component\HttpFoundation\Request
    path:
    vendor/symfony/src/Symfony/Component/
    HttpFoundation/Request.php
    Friday, September 28, 12

    View Slide

  34. use Symfony\Component\ClassLoader\UniversalClassLoader;
    $loader = new UniversalClassLoader();
    $loader->registerNamespaces(array(
    'Zend' => __DIR__.'/path/to/zf'
    ));
    $loader->register();
    Friday, September 28, 12

    View Slide

  35. (B)
    Managing Vendors in your
    project
    Friday, September 28, 12

    View Slide

  36. Composer
    Friday, September 28, 12

    View Slide

  37. {
    "require": {
    "zendframework/ldap": "2.0.x-dev"
    }
    }
    1) Composer.json
    Friday, September 28, 12

    View Slide

  38. $ curl -s https://getcomposer.org/installer | php
    $ php composer.phar install
    2) Composer.phar
    Friday, September 28, 12

    View Slide

  39. require 'vendor/autoload.php';
    use Zend\Ldap\Ldap;
    $options = array(...);
    $ldap = new Ldap($options);
    3) Use It
    Friday, September 28, 12

    View Slide

  40. Friday, September 28, 12

    View Slide

  41. Act 2
    Your friendly, neighborhood
    Symfony Components
    Friday, September 28, 12

    View Slide

  42. The Symfony Components
    • HttpFoundation
    • HttpKernel
    • Event Dispatcher
    • Routing
    • CSSSelector
    • DomCrawler
    • BrowserKit
    • Config
    • Yaml
    • DependencyInjection
    • Security
    @weaverryan
    • OptionsResolver
    • Console
    • Filesystem
    • Finder
    • Locale
    • Process
    • Serializer
    • Templating
    • Form
    • Translation
    • Validator
    Friday, September 28, 12

    View Slide

  43. The Symfony Components
    • HttpFoundation
    • HttpKernel
    • Event Dispatcher
    • Routing
    • CSSSelector
    • DomCrawler
    • BrowserKit
    • Config
    • Yaml
    • DependencyInjection
    • Security
    @weaverryan
    • OptionsResolver
    • Console
    • Filesystem
    • Finder
    • Locale
    • Process
    • Serializer
    • Templating
    • Form
    • Translation
    • Validator
    The “Framework”
    Components
    Friday, September 28, 12

    View Slide

  44. Level 1
    HttpFoundation
    symfony/http-foundation
    Friday, September 28, 12

    View Slide

  45. @weaverryan
    {
    "require": {
    "symfony/http-foundation": "2.1.x-dev"
    }
    }
    php composer.phar install
    // your app
    require 'vendor/autoload.php';
    1
    2
    3
    Fun to Install!
    Friday, September 28, 12

    View Slide

  46. @weaverryan
    Request
    /foo
    Response
    Hi!
    ?
    ?
    ?
    ? ?
    ?
    Mystery
    PHP Code
    Friday, September 28, 12

    View Slide

  47. The Request
    Friday, September 28, 12

    View Slide

  48. GET /foo?p=v1 HTTP/1.1
    Host: knplabs.com
    Accept: text/html
    User-Agent: Mozilla/5.0
    // /foo?p=v1
    $uri = $_SERVER['REQUEST_URI'];
    $p = isset($_GET['p']) ? $_GET['p'] : '';
    $host = $_SERVER['HTTP_HOST'];
    $accept = $_SERVER['HTTP_ACCEPT'];
    $ua = $_SERVER['HTTP_USER_AGENT'];
    Friday, September 28, 12

    View Slide

  49. use Symfony\Component\HttpFoundation\Request;
    $request = Request::createFromGlobals();
    $uri = $request->getPathInfo(); /foo
    $p = $request->query->get('p');
    $host = $request->getHost();
    $accept = $request->headers->get('Accept');
    GET /foo?p=v1 HTTP/1.1
    Host: knplabs.com
    Accept: text/html
    User-Agent: Mozilla/5.0
    Friday, September 28, 12

    View Slide

  50. The Response
    Friday, September 28, 12

    View Slide

  51. HTTP/1.1 200 OK
    Date: Tue, 04 Jun 2011 21:05:05 GMT
    Content-Type: text/html
    Set-Cookie:foo=fooval; path=/; httponly
    Foo!
    header('Content-Type', 'text/html');
    setcookie('foo', 'fooval');
    echo 'Foo!';
    Friday, September 28, 12

    View Slide

  52. HTTP/1.1 200 OK
    Date: Tue, 04 Jun 2011 21:05:05 GMT
    Content-Type: text/html
    Set-Cookie:foo=fooval; path=/; httponly
    Foo!
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\HttpFoundation\Cookie;
    $response = new Response('Foo!');
    $cookie = new Cookie('foo', 'fooval');
    $response->headers->setCookie($cookie);
    $response->send();
    Friday, September 28, 12

    View Slide

  53. A Mini Framework
    Friday, September 28, 12

    View Slide

  54. // not dependable!
    $uri = $_SERVER['REQUEST_URI'];
    ob_start();
    if ($uri == '/') {
    echo 'Homepage! \o/';
    } else {
    echo 'sad missing page :/';
    }
    header('X-TOKEN: Foo');
    ob_end_flush();
    Friday, September 28, 12

    View Slide

  55. $req = Request::createFromGlobals();
    if ($req->getPathInfo() == '/') {
    $res = new Response('Homepage! \o/');
    } else {
    $res = new Response('sad missing page :/');
    }
    $res->headers->set('X-SECRET', 'Foo');
    $res->send();
    Symfony3
    Friday, September 28, 12

    View Slide

  56. Get some learning about
    HttpFoundation
    @weaverryan
    • Docs: http://bit.ly/sf2-http-foundation
    • Code: http://bit.ly/sf2-http-foundation-code
    • API: http://bit.ly/sf2-http-foundation-api
    Friday, September 28, 12

    View Slide

  57. Level 2
    HttpKernel
    symfony/http-kernel
    Friday, September 28, 12

    View Slide

  58. @weaverryan
    Framework
    Request
    Determine
    the controller
    ?
    ? ?
    Execute it
    Flush the Response
    Response
    Friday, September 28, 12

    View Slide

  59. Framework:
    A pattern for converting a
    request into a response
    Friday, September 28, 12

    View Slide

  60. @weaverryan
    Framework
    Request
    Determine
    the controller
    ?
    ? ?
    Execute it
    Flush the Response
    Response
    Friday, September 28, 12

    View Slide

  61. @weaverryan
    HttpKernel
    Request
    Determine
    the controller
    ?
    ? ?
    Execute it
    Flush the Response
    Response
    Friday, September 28, 12

    View Slide

  62. $kernel = new HttpKernel(...);
    $request = Request::createFromGlobals();
    $response = $kernel->handle($request);
    $response->send();
    There be magic inside!
    Friday, September 28, 12

    View Slide

  63. These lines execute your
    Symfony application
    (hint, see - web/app.php)
    Friday, September 28, 12

    View Slide

  64. ... and Drupal 8 too ...
    Friday, September 28, 12

    View Slide

  65. Yea, this is abstract
    Stay Tuned...
    Friday, September 28, 12

    View Slide

  66. Level 3
    EventDispatcher
    symfony/event-dispatcher
    Friday, September 28, 12

    View Slide

  67. @weaverryan
    Event
    Dispatcher
    A classic “observer pattern”
    Listener
    Listener
    Tell me when Liz
    gets to work
    Tell me when Liz
    gets to work
    Friday, September 28, 12

    View Slide

  68. @weaverryan
    Event
    Dispatcher
    • Event Dispatcher: a classic “observer pattern”
    Listener
    Listener
    Yo! I’m at
    work!
    Friday, September 28, 12

    View Slide

  69. @weaverryan
    Event
    Dispatcher
    • Event Dispatcher: a classic “observer pattern”
    Listener
    Listener
    Liz is at
    work!
    Liz is at
    work!
    Friday, September 28, 12

    View Slide

  70. Event
    Dispatcher
    • Event Dispatcher: a classic “observer pattern”
    Listener
    Listener
    She’s the best
    around!
    I’m totally
    going to go talk
    with her!!
    Friday, September 28, 12

    View Slide

  71. Level 4
    Routing
    symfony/routing
    Friday, September 28, 12

    View Slide

  72. @weaverryan
    Router
    Url
    Match against
    a route
    Return info
    about the route
    Route
    Route
    Friday, September 28, 12

    View Slide

  73. $loader = new ClosureLoader();
    $router = new Router($loader, function() {
    $collection = new RouteCollection();
    $route = new Route('/blog/{slug}');
    $collection->add('blog', $route);
    return $collection;
    });
    $results = $router->match('/blog/sflive');
    array(
    'slug' => 'sflive',
    '_route' => 'blog',
    )
    Friday, September 28, 12

    View Slide

  74. $loader = new ClosureLoader();
    $router = new Router($loader, function() {
    $collection = new RouteCollection();
    $route = new Route('/blog/{slug}', array(
    '_controller' => 'SomeBundle:Blog:show'
    ));
    $collection->add('blog', $route);
    return $collection;
    });
    $results = $router->match('/blog/sflive');
    array(
    '_controller' => 'SomeBundle:Blog:show',
    'slug' => 'sflive',
    '_route' => 'blog'
    )
    Friday, September 28, 12

    View Slide

  75. Input: Request Information
    Output: An array of info
    Friday, September 28, 12

    View Slide

  76. Level 5
    A “Framework”
    Friday, September 28, 12

    View Slide

  77. $kernel = new HttpKernel(...);
    $request = Request::createFromGlobals();
    $response = $kernel->handle($request);
    $response->send();
    Friday, September 28, 12

    View Slide

  78. @weaverryan
    HttpKernel::handle()
    HttpFoundation
    +
    EventDispatcher
    +
    Routing (optional)
    =
    Framework
    Friday, September 28, 12

    View Slide

  79. @weaverryan
    HttpKernel::handle()
    Request
    +
    Determine Controller
    +
    Controller Returns a Response
    =
    Response
    Friday, September 28, 12

    View Slide

  80. Homework:
    Hack your Framework
    ... or do Karaoke later... your call
    Friday, September 28, 12

    View Slide

  81. @weaverryan
    HttpKernel::handleRaw()
    private function handleRaw(Request $request, $type = self::MASTER_REQUEST)
    {
    // request
    $event = new GetResponseEvent($this, $request, $type);
    $this->dispatcher->dispatch(KernelEvents::REQUEST, $event);
    if ($event->hasResponse()) {
    return $this->filterResponse($event->getResponse(), $request, $type);
    }
    // load controller
    if (false === $controller = $this->resolver->getController($request)) {
    throw new NotFoundHttpException('Unable to find the controller);
    }
    $event = new FilterControllerEvent($this, $controller, $request, $type);
    $this->dispatcher->dispatch(KernelEvents::CONTROLLER, $event);
    $controller = $event->getController();
    // ... returns a response
    }
    The kewlest code I know about... seriously
    Friday, September 28, 12

    View Slide

  82. @weaverryan
    • Symfony\Component\HttpKernel\HttpKernel::handle()
    http://bit.ly/sf2-http-kernel-code
    • Symfony Framework Important Classes
    Symfony\Component\HttpKernel\EventListener\RouterListener
    - Executes the routing
    Symfomy\Bundle\FrameworkBundle\Controller\ControllerResolver
    - Parses _controller and instantiates the controller object
    step/var_dump()die; the core
    Friday, September 28, 12

    View Slide

  83. Timeline of events in the Symfony Framework
    kernel.request
    kernel.controller
    kernel.response
    Friday, September 28, 12

    View Slide

  84. Profile events in the Symfony Framework
    Friday, September 28, 12

    View Slide

  85. The Symfony Components
    • HttpFoundation
    • HttpKernel
    • Event Dispatcher
    • Routing
    • CSSSelector
    • DomCrawler
    • BrowserKit
    • Config
    • Yaml
    • DependencyInjection
    • Security
    @weaverryan
    • OptionsResolver
    • Console
    • Filesystem
    • Finder
    • Locale
    • Process
    • Serializer
    • Templating
    • Form
    • Translation
    • Validator
    Awesome
    Tools
    Friday, September 28, 12

    View Slide

  86. Process
    symfony/process
    Now with more
    Windows Love!
    Friday, September 28, 12

    View Slide

  87. @weaverryan
    {
    "require": {
    "symfony/process": "2.1.x-dev"
    }
    }
    Find Symfony’s Process on Packagist.org
    php composer.phar install
    1
    2
    3
    // your app
    require 'vendor/autoload.php';
    Friday, September 28, 12

    View Slide

  88. // dinner.php
    for ($i = 1; $i <= 3; $i++) {
    sleep(1);
    echo sprintf("Cooking... %s\n", $i);
    }
    echo "DING! \n";
    External Script to Cook Dinner
    Friday, September 28, 12

    View Slide

  89. Run the script synchronously
    Friday, September 28, 12

    View Slide

  90. // app.php
    require 'vendor/autoload.php';
    use Symfony\Component\Process\Process;
    $process = new Process('php dinner.php');
    // if dinner takes longer than 5 seconds
    // to cook, freak out!
    $process->setTimeout(5);
    $process->run(function($type, $buffer) {
    echo $buffer;
    });
    // executed after the command finishes
    if (!$process->isSuccessful()) {
    throw new \Exception('Process misbehaved')
    }
    Friday, September 28, 12

    View Slide

  91. Friday, September 28, 12

    View Slide

  92. Run the script asynchronously
    Friday, September 28, 12

    View Slide

  93. $process = new Process('php dinner.php');
    $process->start();
    // do more work here
    echo "WORKING!!! \n";
    while ($process->isRunning()) {
    // wait for the process to finish
    };
    echo $process->getOutput();
    Friday, September 28, 12

    View Slide

  94. Interacting via Stdin
    Friday, September 28, 12

    View Slide

  95. $process = new Process('php dinner.php');
    $process->setStdin('turkey');
    “turkey” is read from Stdin
    Friday, September 28, 12

    View Slide

  96. $process = new Process('php dinner.php');
    $process->run(function($type, $buffer) {
    if ($type == 'err') {
    // perhaps do some logging?
    echo $buffer;
    }
    });
    Handling things that blow up!
    if (!$process->isSuccessful()) {
    echo sprintf(
    "Process failed! Exit code %s, '%s'\n",
    $process->getExitCode(),
    $process->getExitCodeText()
    );
    }
    Friday, September 28, 12

    View Slide

  97. Find out more about Process
    @weaverryan
    • Docs: http://bit.ly/sf2-process
    • Code: http://bit.ly/sf2-process-code
    • API: http://bit.ly/sf2-process-api
    Friday, September 28, 12

    View Slide

  98. SPORK!
    @kriswallsmith
    $manager = new Spork\ProcessManager();
    $manager->fork(function() {
    // do something in another process!
    return 'Hello from '.getmypid();
    })->then(function(Spork\Fork $fork) {
    // do something in the parent process afterwards
    echo "{$fork->getPid()} says '{$fork->getResult()}'";
    });
    Fork yourself some more PHP
    https://github.com/kriswallsmith/spork
    Friday, September 28, 12

    View Slide

  99. Finder
    symfony/finder
    Friday, September 28, 12

    View Slide

  100. From the Fablog
    http://fabien.potencier.org/article/44/php-iterators-and-
    streams-are-awesome
    use Symfony\Components\Finder\Finder;
    $s3 = new \Zend_Service_Amazon_S3($key, $secret);
    $s3->registerStreamWrapper("s3");
    $finder = new Finder();
    $finder->name('photos*')
    ->size('< 100K')
    ->date('since 1 hour ago');
    foreach ($finder->in('s3://bucket-name') as $file) {
    // do something
    print $file->getFilename()."\n";
    }
    Friday, September 28, 12

    View Slide

  101. Find(er) out more about Finder
    @weaverryan
    • Docs: http://bit.ly/sf2-finder
    • Code: http://bit.ly/sf2-finder-code
    • API: http://bit.ly/sf2-finder-api
    Friday, September 28, 12

    View Slide

  102. Filesystem
    symfony/filesystem
    New in 2.1!
    Friday, September 28, 12

    View Slide

  103. @weaverryan
    {
    "require": {
    "symfony/filesystem": "2.1.x-dev"
    }
    }
    Find Symfony’s Filesystem on Packagist.org
    php composer.phar update symfony/filesystem
    1
    2
    3
    // your app
    require 'vendor/autoload.php';
    Friday, September 28, 12

    View Slide

  104. // ...
    use Symfony\Component\Filesystem\Filesystem;
    $filesystem = new Filesystem();
    $filesystem->copy(
    'cowboy.jpg',
    's3://my-bucket/cowboy.jpg'
    );
    $filesystem->copy(
    's3://my-bucket/rodeo.mov',
    'rodeo.mov'
    );
    $filesystem->mirror(
    'thumbnails',
    's3://my-bucket/thumbnails'
    );
    Friday, September 28, 12

    View Slide

  105. // ...
    use Symfony\Component\Filesystem\Filesystem;
    use Symfony\Component\Finder\Finder;
    $finder = new Finder();
    $finder->name('*.jpg')
    ->date('since 1 hour ago');
    ->in('thumbs');
    $filesystem = new Filesystem();
    $filesystem->chmod($finder, 0777);
    Friday, September 28, 12

    View Slide

  106. // ...
    use Symfony\Component\Filesystem\Filesystem;
    $filesystem = new Filesystem();
    $filesystem->touch('foo.txt');
    $filesystem->chmod('foo.txt', 0777);
    $filesystem->symlink('/some/dir', '/symlink/target')
    Friday, September 28, 12

    View Slide

  107. Find out more about Filesystem
    @weaverryan
    • Docs: http://bit.ly/sf2-filesystem
    • Code: http://bit.ly/sf2-filesystem-code
    • API: http://bit.ly/sf2-filesystem-api
    Friday, September 28, 12

    View Slide

  108. Console
    symfony/console
    Friday, September 28, 12

    View Slide

  109. Friday, September 28, 12

    View Slide

  110. // command.php
    $loader = require 'vendor/autoload.php';
    $loader->add('App', __DIR__);
    use Symfony\Component\Console\Application;
    use App\Command\EchoCommand;
    $app = new Application();
    $app->add(new EchoCommand());
    $app->run();
    Friday, September 28, 12

    View Slide

  111. namespace App\Command;
    use Symfony\Component\Console\Command\Command;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Output\OutputInterface;
    class EchoCommand extends Command
    {
    protected function configure()
    {
    $this->setName('echo')->addArgument('msg');
    }
    public function execute(
    InputInterface $input,
    OutputInterface $output)
    {
    $output->writeln('Yo '.$input->getArgument('msg'));
    }
    }
    Friday, September 28, 12

    View Slide

  112. Output with pretty colors
    Friday, September 28, 12

    View Slide

  113. Find out more about Command
    @weaverryan
    • Docs http://bit.ly/sf2-console
    • Code http://bit.ly/sf2-console-code
    • API http://api.symfony.com/master/namespaces.html
    -> and search for “Console”
    Friday, September 28, 12

    View Slide

  114. If you download Composer
    in the next 5 minutes, we’ll
    throw in a special gift!
    Friday, September 28, 12

    View Slide

  115. CssSelector + DomCrawler
    symfony/css-selector
    symfony/dom-crawler
    Friday, September 28, 12

    View Slide

  116. require 'vendor/autoload.php';
    use Symfony\Component\DomCrawler\Crawler;
    $html = <<


    Hello World!
    Hello Crawler!


    HTML;
    $crawler = new Crawler($html);
    $crawler->filter('p')->eq(0)->attr('class');
    $crawler->filter('p')->eq(1)->text();
    Friday, September 28, 12

    View Slide

  117. Goutte!
    Friday, September 28, 12

    View Slide

  118. Config
    symfony/config
    Friday, September 28, 12

    View Slide

  119. Config
    @weaverryan
    • Load configuration from many formats (YAML,
    PHP files, XML)
    • Config Validation
    • Caching for parsed config
    Friday, September 28, 12

    View Slide

  120. Validator
    symfony/validator
    Friday, September 28, 12

    View Slide

  121. Shh... a little setup
    Friday, September 28, 12

    View Slide

  122. require 'vendor/autoload.php';
    use Symfony\Component\Validator\Validator;
    use Symfony\Component\Validator\Mapping\ClassMetadataFactory;
    use Symfony\Component\Validator\ConstraintValidatorFactory;
    // a little setup
    $metadata = new ClassMetadataFactory();
    $constraintFactory = new ConstraintValidatorFactory();
    $validator = new Validator($metadata, $constraintFactory);
    Friday, September 28, 12

    View Slide

  123. use Symfony\Component\Validator\Constraints\Email;
    $value = 'ryan[AT]knplabs.com';
    $email = new Email();
    $email->message = 'Invalid! You entered {{ value }}';
    $errors = $validator->validateValue($value, $email);
    if (count($errors) > 0) {
    echo strtr(
    $errors[0]->getMessageTemplate(),
    $errors[0]->getMessageParameters()
    );
    }
    Friday, September 28, 12

    View Slide

  124. 34 Core Validators and counting
    • String length
    • Regular expressions
    • Ip addresses
    • Dates
    • Collections
    • File size, mime-type, etc
    ... and the brand new Luhn validator
    for credit card numbers thanks to
    @merk ----------------------------------->
    @weaverryan
    See the “Reference”
    section of the docs
    Friday, September 28, 12

    View Slide

  125. But wait there’s more!
    Friday, September 28, 12

    View Slide

  126. More Components
    • DependencyInjection
    • Security
    • OptionsResolver
    • Locale
    • Serializer
    • Templating
    • Form
    • Translation
    @weaverryan
    Friday, September 28, 12

    View Slide

  127. Many components are easy
    Friday, September 28, 12

    View Slide

  128. Some are still wtf-hard
    Friday, September 28, 12

    View Slide

  129. (cough) Security (cough)
    Friday, September 28, 12

    View Slide

  130. Documentation
    Documentation
    Documentation
    Friday, September 28, 12

    View Slide

  131. The Security Component
    https://github.com/symfony/symfony-docs/pull/1604
    WIP by @matthiasnoback
    Friday, September 28, 12

    View Slide

  132. Act 3
    Kicking ass in the new
    PHP eco-system
    Friday, September 28, 12

    View Slide

  133. The PHP Ecosphere
    • Symfony
    • Zend Framework
    • EZ Components
    • Drupal
    • ...
    • Individuals
    @weaverryan
    Symfony is only one part of the picture
    What other stuff exists?
    Friday, September 28, 12

    View Slide

  134. How do we find good
    libraries?
    Friday, September 28, 12

    View Slide

  135. Friday, September 28, 12

    View Slide

  136. Friday, September 28, 12

    View Slide

  137. Some Favorites
    Friday, September 28, 12

    View Slide

  138. Mink
    behat/mink
    http://mink.behat.org/
    By @everzet, written on
    Fabien’s childhood computer
    Friday, September 28, 12

    View Slide

  139. Command a browser, find elements, click
    them, and fill out forms
    $driver = new \Behat\Mink\Driver\SahiDriver('firefox');
    $session->visit('http://my_project.dev/some_page.php');
    $page = $session->getPage();
    $anchor = $page->find('css', '.something');
    $anchor->click();
    // get the content of the new page
    echo $page->getContent();
    Friday, September 28, 12

    View Slide

  140. Monolog
    monolog/monolog
    https://github.com/Seldaek/monolog
    Your Friend Jordi
    Friday, September 28, 12

    View Slide

  141. A Logger, where bells and whistles
    come standard
    use Monolog\Logger;
    use Monolog\Handler\StreamHandler;
    use Monolog\Handler\FirePHPHandler;
    // Create the logger
    $logger = new Logger('my_logger');
    $logger->pushHandler(new StreamHandler(
    __DIR__.'/my_app.log'
    ));
    $logger->pushHandler(new FirePHPHandler());
    $logger->addInfo('My logger is now ready');
    Friday, September 28, 12

    View Slide

  142. Zend Framework 2
    They have some stuff
    Friday, September 28, 12

    View Slide

  143. Yay Find More!
    Friday, September 28, 12

    View Slide

  144. Epilogue
    4 Reasons to get
    silly-excited about
    the Future
    Friday, September 28, 12

    View Slide

  145. 1) Look for Participation &
    Consolidation
    Friday, September 28, 12

    View Slide

  146. Shared Building-blocks
    • Drupal
    • phpBB
    • Midgard
    • Zikula
    • ez Publish 5
    • ...
    @weaverryan
    Friday, September 28, 12

    View Slide

  147. Less Library Duplication?
    • Zend/Form
    • Zend/Serializer
    • Zend/Http
    • Zend/EventManager
    • Zend/Log
    • Zend/Navigation
    • ...
    @weaverryan
    • Symfony/Form
    • Symfony/Serializer
    • Symfony/HttpFoundation
    • Symfony/EventDispatcher
    • Monlog
    • KnpMenu
    • ...
    Friday, September 28, 12

    View Slide

  148. 2) More high quality,
    community-grown libraries
    Friday, September 28, 12

    View Slide

  149. Solving 1 specific problem
    is a low barrier to entry
    Friday, September 28, 12

    View Slide

  150. Find them, fork them.
    Friday, September 28, 12

    View Slide

  151. Write their docs :)
    Friday, September 28, 12

    View Slide

  152. Programmers that write
    docs get hugs
    Friday, September 28, 12

    View Slide

  153. 3) Easier upgrades
    Friday, September 28, 12

    View Slide

  154. 4) Grow your Community
    Friday, September 28, 12

    View Slide

  155. Solutions exist outside of
    your framework
    Friday, September 28, 12

    View Slide

  156. Fabien will not come to your
    house and tell you about them
    Friday, September 28, 12

    View Slide

  157. Cast your vote by using the
    best libraries and improving
    them
    Friday, September 28, 12

    View Slide

  158. and realize the power of
    the entire PHP community
    Friday, September 28, 12

    View Slide

  159. Thanks...
    Ryan Weaver
    @weaverryan
    Friday, September 28, 12

    View Slide

  160. ... and we love you!
    Ryan Weaver
    @weaverryan
    Ryan Weaver
    @weaverryan
    https://joind.in/7218
    Friday, September 28, 12

    View Slide