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

Symfony2 Components. How not to reinvent the wheel.

Roma
November 10, 2012

Symfony2 Components. How not to reinvent the wheel.

WebConf Riga 2012, 10.11.2012
Evercode Talks №1, 08.11.2012
Don't reinvent the wheel, use the existing one, make them better, enjoy and don't waste your time. Symfony2 framework has a remarkable set of standalone decoupled components for various task of web development. Let's see how we can use them for our tasks.

Roma

November 10, 2012
Tweet

More Decks by Roma

Other Decks in Programming

Transcript

  1. Don’t Reinvent The Wheel, Unless You Plan on Learning More

    About Wheels. Jeff Atwood (http:/ /www.codinghorror.com/blog/2009/02/dont-reinvent-the-wheel-unless-you-plan-on-learning- more-about-wheels.html)
  2. Symfony Components Beside being a full-stack framework, Symfony is also

    a set of decoupled and standalone components. Symfony Components implement common features needed to develop websites.
  3. Reasons Decoupled and Standalone Highly tested Clean API Widely adopted

    Audited for security issues by an independent company There are people (great community)
  4. Components ClassLoader Config DependencyInjection EventDispatcher HttpFoundation HttpKernel Routing Templating BrowserKit

    Process Console Finder CssSelector DomCrawler Form Locale Serializer Yaml Validator Translation
  5. Components ClassLoader Config DependencyInjection EventDispatcher HttpFoundation HttpKernel Routing Templating BrowserKit

    Process Console Finder CssSelector DomCrawler Form Locale Serializer Yaml Validator Translation
  6. Installation { "require": { "symfony/console": "2.1.*", "symfony/process": "2.1.*", "symfony/finder": "2.1.*",

    "symfony/form": "2.1.*", "symfony/validator": "2.1.*", "symfony/config": "2.1.*", "symfony/translation": "2.1.*", "symfony/security": "2.1.*" ... } } $ composer install require_once __DIR__.'/../vendor/autoload.php';
  7. HttpFoundation use Symfony\Component\HttpFoundation\Request; $request = Request::createFromGlobals(); $input = $request->get('name', 'World');

    // the URI minus any query parameters $request->getPathInfo(); // retrieve SERVER variables $request->server->get('HTTP_HOST'); // retrieves an instance of UploadedFile identified by foo $request->files->get('foo');
  8. HttpFoundation // COOKIE value $request->cookies->get('PHPSESSID'); // HTTP request header $request->headers->get('host');

    $request->getMethod(); // GET, POST, PUT, DELETE, HEAD // simulate a request $request = Request::create('/awesome.php?say=wooohooo');
  9. HttpFoundation use Symfony\Component\HttpFoundation\Response; $response = new Response(); $response->setContent(“What’s up, Doc?”);

    $response->setStatusCode(200); $response->headers->set('Content-Type', 'text/html'); // HTTP cache headers $response->setMaxAge(10);
  10. Finder use Symfony\Component\Finder\Finder; $finder = new Finder(); $finder->files() ->in(__DIR__) ->in(__DIR__.'/../data')

    ->exclude('crap') ; foreach ($finder as $file) { print $file->getRealpath()."\n"; print $file->getFilename()."\n"; }
  11. Console The Console component allows you to create command-line commands.

    Your console commands can be used for any recurring task, such as cronjobs, imports, or other batch jobs.
  12. Console class ParseCommand extends Command { protected function configure() {

    $this ->setName('parse') ->setDescription('Parses cached information') ->addArgument('date', InputArgument::OPTIONAL, "Put in some date.", date('Y-m-d')) ; } }
  13. Console protected function execute(InputInterface $input, OutputInterface $output) { $date =

    $input->getArgument('date'); if (empty($date)) { $date = date('Y-m-d'); } $formatter = new CsvFormatter(); $formatter->process($date); $output->writeln('<info>operation finished</info>'); }
  14. CssSelector $document = new \DOMDocument(); $document->preserveWhiteSpace = false; $document->loadHTML($html); $xpath

    = new \DOMXPath($document); $blocks = $xpath->query( CssSelector::toXPath('div.filters ul li b a') );
  15. DomCrawler $document = new \DOMDocument(); $document->preserveWhiteSpace = false; $document->loadHTML($html); $xpath

    = new \DOMXPath($document); $blocks = $xpath->query( CssSelector::toXPath('div.filters ul li b a') );
  16. DomCrawler use Symfony\Component\DomCrawler\Crawler; use Symfony\Component\CssSelector\CssSelector; $crawler = new Crawler($html); $crawler

    = $crawler->filterXPath( CssSelector::toXPath('div.filters ul li b a') ); $crawler = $crawler->filter('div.filters ul li b a');
  17. DomCrawler $crawler->filter('body > p')->first(); $crawler->filter('body > p')->last(); $crawler->filter('body > p')->siblings();

    $crawler->filter('body > p')->nextAll(); $crawler->filter('body > p')->previousAll(); $crawler->filter('body')->children(); $crawler->filter('body > p')->parents();
  18. DomCrawler $link = $crawler->selectLink('follow the rabbit')->link(); $uri = $link->getUri(); $form

    = $crawler->selectButton('validate')->form(); $form = $crawler->selectButton('validate')->form(array( 'name' => 'Just Bugs', )); $uri = $form->getUri();
  19. DomCrawler use Goutte\Client; // make a real request to an

    external site $client = new Client(); $crawler = $client->request('GET', 'https://github.com/login'); // select the form and fill in some values $form = $crawler->selectButton('Log in')->form(); $form['login'] = 'rabbitcoder'; $form['password'] = 'Carrot123'; // submit that form $crawler = $client->submit($form);
  20. Form Form provides tools for defining forms, rendering and binding

    request data to related models. Furthermore it provides integration with the Validation component.
  21. Form namespace App\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Validator\Constraints as

    Assert; use Symfony\Component\OptionsResolver\OptionsResolverInterface; class RegisterType extends AbstractType { ... public function getName() { return 'register'; } }
  22. Form public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('event',

    'choice', array( 'choices' => $events, 'constraints' => new Assert\Choice(array_keys($events)), 'required' => true, 'attr' => array( 'class' => 'input-xlarge' ), )) ->add('first_name', 'text', array( 'constraints' => new Assert\NotBlank(), 'required' => true, )) }
  23. Form $app->match('/', function (Request $request) use ($app) { $form =

    $app['form.factory']->create( new RegisterType($app['event_service']) ); if ('POST' == $request->getMethod()) { $form->bind($request); if ($form->isValid()) { $data = $form->getData(); // ... return $app->redirect('success'); } } return $app['twig']->render('index.html.twig', array( 'form' => $form->createView() )); });
  24. Security Security provides an infrastructure for sophisticated authorization systems, which

    makes it possible to easily separate the actual authorization logic from so called user providers that hold the users credentials.
  25. Security $app->register(new Silex\Provider\SecurityServiceProvider()); $app['security.firewalls'] = array( 'admin' => array( 'pattern'

    => '^/admin', 'http' => true, 'users' => array( 'admin_login' => array( 'ROLE_ADMIN', 'encrypted_pass' ), ), ), );
  26. Use cases? Refactoring New apps Integrating in existent code Inventing

    the wheel (yet another framework?) You name it!
  27. Want more? Composer (http:/ /getcomposer.org/) Packagist (https:/ /packagist.org/) Silex (http:/

    /silex.sensiolabs.org/) Twig (http:/ /twig.sensiolabs.org/) SwiftMailer (http:/ /swiftmailer.org/) KnpBundles (http:/ /knpbundles.com/)
  28. Sources http:/ /symfony.com/components “Create your own framework... on top of

    the Symfony2 Components” by Fabien Potencier Source code http:/ /www.php-fig.org/
  29. Reinvent away. Most of our current technology sucks, and even

    if it didn't, who am I to try and stop you? Bob Lee (http:/ /blog.crazybob.org/2007/09/why-reinvent-wheel.html)