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

Symfony2 Components. Как не изобретать велосипе...

Roma
March 02, 2013

Symfony2 Components. Как не изобретать велосипед (DrupalCafe version)

DrupalCafe #3 Spb
Не изобретайте велосипеды, катайтесь на них, улучшайте их, получайте удовольствие и не тратьте время зря. Фреймворк Symfony2 предоставляет отличный набор независимых компонентов для различных задач веб-разработки. Давайте посмотрим, как можно их использовать для решения наших задач.

Roma

March 02, 2013
Tweet

More Decks by Roma

Other Decks in Programming

Transcript

  1. Symfony2 Components. Как не изобретать велосипед Роман Лапин, Evercode Lab

    @memphys, [email protected] Обновлено и адаптировано специально для DrupalCafe #3 ;)
  2. 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
  3. PHP < 5.3 Много библиотек, фреймворков и вообще готового кода

    Большое коммьюнити PEAR (это боль) НО! Copy + Paste :(
  4. 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.
  5. Symfony2+Drupal=<3 Today, I want to officially announce that Drupal will

    adopt some of the Symfony Components for their upcoming version 8. And I'm not talking about some minor components, they are embracing our vision and they will use the major components that will allow them to build a great low-level architecture for Drupal 8: HttpFoundation, HttpKernel, Routing, EventDispatcher, DependencyInjection, and ClassLoader. Fabien Potencier - March 22, 2012 http:/ /symfony.com/blog/symfony2-meets-drupal-8
  6. Компоненты ClassLoader Config DependencyInjection EventDispatcher HttpFoundation HttpKernel Routing Templating BrowserKit

    Process Console Finder CssSelector DomCrawler Form Locale Serializer Yaml Validator Translation
  7. Компоненты ClassLoader Config DependencyInjection EventDispatcher HttpFoundation HttpKernel Routing Templating BrowserKit

    Process Console Finder CssSelector DomCrawler Form Locale Serializer Yaml Validator Translation
  8. Компоненты в Drupal8 ClassLoader Config DependencyInjection EventDispatcher HttpFoundation HttpKernel Routing

    Templating BrowserKit Process Console Finder CssSelector DomCrawler Form Locale Serializer Yaml Validator Translation
  9. Причины Независимые и изолированные Покрыты тестами Очень приятный API Широкое

    распространение Проведен независимый аудит безопасности
  10. Установка { "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';
  11. { "name": "drupal/drupal", "description": "Drupal is an open source content

    management platform powering millions of websites and applications.", "license": "GPL-2.0+", "repositories": [{ "type": "vcs", "url": "https://github.com/msonnabaum/phpunit.git" } ], "require": { "symfony/class-loader": "2.2.0-BETA2", "symfony/dependency-injection": "2.2.0-BETA2", "symfony/event-dispatcher": "2.2.0-BETA2", "symfony/http-foundation": "2.2.0-BETA2", "symfony/http-kernel": "2.2.0-BETA2", "symfony/routing": "2.2.0-BETA2", "symfony/serializer": "2.2.0-BETA2", "symfony/validator": "2.2.0-BETA2", "symfony/yaml": "2.2.0-BETA2", "twig/twig": "1.12.1", "doctrine/common": "2.3.0", "guzzle/http": "3.1.0", "kriswallsmith/assetic": "1.1.0-alpha1", "symfony-cmf/routing": "dev-master#ea4a10", "easyrdf/easyrdf": "0.8.0-beta.1", "phpunit/phpunit": "3.7 as dev-3.7" }, "minimum-stability": "dev" }
  12. ClassLoader The ClassLoader Component loads your project classes automatically if

    they follow some standard PHP conventions. { "require": { "symfony/class-loader": "2.2.0-BETA2", } }
  13. ClassLoader require_once '/path/to/src/Symfony/Component/ClassLoader/ UniversalClassLoader.php'; use Symfony\Component\ClassLoader\UniversalClassLoader; $loader = new UniversalClassLoader();

    // You can search the include_path as a last resort. $loader->useIncludePath(true); // ... register namespaces and prefixes here - see below $loader->register();
  14. HttpFoundation The Symfony2 HttpFoundation component replaces these default PHP global

    variables and functions by an Object-Oriented layer. { "require": { "symfony/http-foundation": "2.2.0-BETA2", } }
  15. 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');
  16. 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');
  17. 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);
  18. Routing The Routing Component maps an HTTP request to a

    set of configuration variables. { "require": { "symfony/routing": "2.2.0-BETA2", } }
  19. Routing use Symfony\Component\Routing\Matcher\UrlMatcher; use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\Route; $route

    = new Route( '/archive/{month}', // path array('controller' => 'showArchive'), // default values array('month' => '[0-9]{4}-[0-9]{2}'), // requirements array() // options ); $routes = new RouteCollection(); $routes->add('route_name', $route); $context = new RequestContext($_SERVER['REQUEST_URI']); $matcher = new UrlMatcher($routes, $context); $parameters = $matcher->match('/archive/2012-01'); // array('controller' => 'showArchive', '_route' => 'route_name')
  20. HttpKernel HttpKernel provides the building blocks to create flexible and

    fast HTTP-based frameworks. { "require": { "symfony/http-kernel": "2.2.0-BETA2", } }
  21. HttpKernelInterface interface HttpKernelInterface { /** * Handles a Request to

    convert it to a Response. * * @param Request $request A Request instance * * @return Response A Response instance */ function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true); }
  22. HttpKernelInterface $routes = new RouteCollection(); $routes->add('hello', new Route('/hello', array('_controller' =>

    function (Request $request) { return new Response(sprintf("Hello %s", $request->get('name'))); } ))); $request = Request::createFromGlobals(); $context = new RequestContext(); $context->fromRequest($request); $matcher = new UrlMatcher($routes, $context); $dispatcher = new EventDispatcher(); $dispatcher->addSubscriber(new RouterListener($matcher)); $resolver = new ControllerResolver(); $kernel = new HttpKernel($dispatcher, $resolver); $kernel->handle($request)->send();
  23. Finder The Finder Component finds files and directories via an

    intuitive fluent interface. { "require": { "symfony/finder": "2.2.0-BETA2", } }
  24. 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"; }
  25. 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. { "require": { "symfony/console": "2.2.0-BETA2", } }
  26. 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')) ; } }
  27. 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>'); }
  28. Form Form provides tools for defining forms, rendering and binding

    request data to related models. Furthermore it provides integration with the Validation component. { "require": { "symfony/form": "2.2.0-BETA2", } }
  29. 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'; } }
  30. 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, )) }
  31. 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() )); });
  32. Twig The flexible, fast, and secure template engine for PHP

    { "require": { "twig/twig": "1.12.1", } }
  33. Twig <?php echo $var ?> <?php echo htmlspecialchars($var, ENT_QUOTES, 'UTF-8')

    ?> {{ var }} {{ var|escape }} {% for user in users %} * {{ user.name }} {% else %} No user have been found. {% endfor %} {% extends "layout.html" %} {% block content %} Content of the page... {% endblock %}
  34. Что-нибудь еще? Silex (http:/ /silex.sensiolabs.org/) Twig (http:/ /twig.sensiolabs.org/) SwiftMailer (http:/

    /swiftmailer.org/) KnpBundles (http:/ /knpbundles.com/) Symfony2 CMF (http:/ /cmf.symfony.com/)
  35. Источники http:/ /symfony.com/components “Create your own framework... on top of

    the Symfony2 Components” by Fabien Potencier Source code http:/ /www.php-fig.org/ https:/ /igor.io/
  36. 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)
  37. Будьте не просто Drupal разработчиком, или Symfony разработчиком, или даже

    PHP или Ruby разработчиком. Смотрите шире, обменивайтесь идеями, ищите решения действительно важных и новых проблем.