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

Aumente o reconhecimento da sua carreira atravé...

Aumente o reconhecimento da sua carreira através da certificação Symfony

Symfony hoje é um ambiente estável que é bem conhecido e reconhecido internacionalmente. Nesta palestra mostrarei como aumentar suas chances de obter a certificação Symfony utilizando as técnicas que utilizei para alcançar a certificação. Também falarei sobre quais são as vantagens de se destacar através de uma certificação Symfony.

Avatar for Hallison Boaventura

Hallison Boaventura

May 16, 2019
Tweet

Other Decks in Education

Transcript

  1. Aumente o reconhecimento da sua carreira através da certificação Symfony

    Hallison Boaventura {github,twitter}.com/hallboav
  2. @hallboav • Reputação ◦ 119 packages ◦ 2,5 bilhões downloads

    • Referências ◦ Drupal ◦ Composer ◦ Laravel Por que Symfony?
  3. @hallboav • Open Source ◦ MIT - Massachusetts Institute of

    Technology • Inovação ◦ Symfony Panther, Messenger, Mercure, Flex, etc. • Interoperabilidade ◦ Liberdade ◦ Symfony Contracts Por que Symfony?
  4. @hallboav • Promessa de compatibilidade com versões anteriores ◦ Versionamento

    semântico ◦ Guia de uso do código do Symfony • Processo de entregas ◦ Modelo de entregas de versões baseado no tempo ▪ Patches a cada mês ▪ Minor version a cada seis mêses (maio, novembro) ▪ Major version a cada dois anos Por que Symfony?
  5. Symfony FTW! @hallboav • Diversidade de pensamentos (CARE) • Segurança,

    performance, inovação, etc. • Ótima arquitetura (extensível, direta, etc.) • Excelentes componentes ◦ Console tem +138 milhões downloads no packagist
  6. Aplicações que já escrevi utilizando Symfony @hallboav • Gerador de

    relatórios de um firewall de mercado ◦ FW > Syslog > Node.js > MongoDB > PHP > MongoDB ◦ Console, Progress Bar, Question Helper, Formatter Helper, Validator, Lock, Yaml, Config, OptionsResolver, Finder, Filesystem, etc. • Silex 2 JWT Security Service Provider ◦ Symfony Security Component
  7. Aplicações que já escrevi utilizando Symfony @hallboav • Backend de

    app para consulta de saldo do cartão de alimentação ◦ DomCrawler, CssSelector, Goutte (Non-Symfony) • Conversor de código do Zend Framework v2 para o v3 dentro da estrutura do Itamaraty ◦ Finder, Console, etc.
  8. Aplicações que já escrevi utilizando Symfony @hallboav • Lançador de

    registros de pontos ◦ Symfony Cache, Config, DomCrawler, etc.
  9. @hallboav Técnicas que utilizei para alcançar a certificação • Prática

    • Análise do código • Xdebug • Documentação • Lista de estudo com os tópicos e subtópicos exigidos pela Symfony
  10. @hallboav • SymfonyCasts (tutorials) (oficial) ◦ https://symfonycasts.com • Use uma

    lista para organizar a leitura da documentação ◦ https://thomasberends.github.io/symfony-certification -preparation-list ◦ https://symfony.com/doc/current/index.html (menu guia esquerda) • Contribua para a documentação Minhas recomendações além das técnicas que utilizei
  11. @hallboav Minhas recomendações além das técnicas que utilizei • Faça

    pequenos sistemas com os componentes standalones para estudá-los • Leia (constantemente) livros e blogs ◦ https://leanpub.com/symfony-selfstudy (livro) ◦ https://leanpub.com/a-year-with-symfony (livro) ◦ https://symfony.com/blog ◦ https://andreiabohner.org ◦ http://fabien.potencier.org
  12. @hallboav • Use a ferramenta Certificationy ◦ https://github.com/certificationy/certificationy-cli • Baixar

    documentação offline em formato PDF ◦ https://symfony.com/doc/current/index.html (EOP) • Veja a apresentação do Tobias Nyholm com o título "Deep dive into Symfony 4 internals" Minhas recomendações além das técnicas que utilizei
  13. class SymfonyMug { const CAPACITY = 100.0; protected $amount =

    0.0; public function fill(): void { $this->amount = self::CAPACITY; } public function isEmpty(): bool { return 0 === $this->amount; } // ... } class SymfonyMugEmptyEvent extends Event { const EMPTY = 'symfony_mug.empty'; protected $mug; public function __construct(SymfonyMug $mug) { $this->mug = $mug; } public function getMug(): SymfonyMug { return $this->mug; } } use Symfony\Component\EventDispatcher\Event;
  14. use Symfony\Component\EventDispatcher\EventSubscriberInterface; class SymfonyMugSubscriber extends EventSubscriberInterface { public static function

    getSubscribedEvents() { return [ SymfonyMugEmptyEvent::EMPTY => 'onEmpty', // O mesmo evento pode ser manipulado por dois métodos diferentes // SymfonyMugEmptyEvent::EMPTY => [ // ['onEmptyPre', 8], // ['onEmptyPost', -8], // ], ]; } public function onEmpty(SymfonyMugEmptyEvent $event): void { $event->getMug()->fill(); } }
  15. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $dispatcher->addSubscriber(new SymfonyMugSubscriber()); $mug =

    new SymfonyMug(); // ... if ($mug->isEmpty()) { // Criamos um evento de caneca vazia $event = new SymfonyMugEmptyEvent($mug); // Disparamos o evento para quem estiver observando-o $dispatcher->dispatch(SymfonyMugEmptyEvent::EMPTY, $event); }
  16. use Symfony\Component\HttpFoundation\Request; // Request::createFromGlobals(); $request = Request::create($uri = '/books?foo=bar', $method

    = 'GET', $parameters = [], $cookies = [], $files = [], $server = [], $content = null); echo 'Method: ', var_export($request->getMethod(), true), PHP_EOL; echo 'Scheme: ', var_export($request->getScheme(), true), PHP_EOL; echo 'HttpHost: ', var_export($request->getHttpHost(), true), PHP_EOL; echo 'RequestUri: ', var_export($request->getRequestUri(), true), PHP_EOL; echo 'PathInfo: ', var_export($request->getPathInfo(), true), PHP_EOL; echo 'QueryString: ', var_export($request->getQueryString(), true), PHP_EOL; echo 'Uri: ', var_export($request->getUri(), true), PHP_EOL; // Method: 'GET' // Scheme: 'http' // HttpHost: 'localhost' // RequestUri: '/books?foo=bar' // PathInfo: '/books' // QueryString: 'foo=bar' // Uri: 'http://localhost/books?foo=bar'
  17. use Symfony\Component\HttpFoundation\Response; $response = new Response( $content = '{"books":[{"isbn":"9785189880940"},{"isbn":"9790069769536"}]}', $status

    = 200, $headers = ['Content-Type' => 'application/json'] ); echo 'Content: ', var_export($response->getContent(), true), PHP_EOL; echo 'StatusCode: ', var_export($response->getStatusCode(), true), PHP_EOL; echo 'Content-Type: ', var_export($response->headers->get('Content-Type'), true), PHP_EOL; // Content: '{"books":[{"isbn":"9785189880940"},{"isbn":"9790069769536"}]}' // StatusCode: 200 // Content-Type: 'application/json'
  18. namespace Symfony\Component\HttpKernel; use Symfony\Component\HttpFoundation\Request; /** * @author Fabien Potencier <[email protected]>

    */ interface HttpKernelInterface { const MASTER_REQUEST = 1; const SUB_REQUEST = 2; /** * Handles a Request to convert it to a Response. */ public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true); }
  19. use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\HttpKernelInterface; class SfLiveKernel implements HttpKernelInterface

    { public function handle(Request $request, $type = 1, $catch = true) { if ('/blackfire' === $request->getPathInfo()) { return new Response('<a href="https://blackfire.io">Blackfire</a>'); } else if ('/darkmira' === $request->getPathInfo()) { return new Response('<a href="https://php.darkmiratour.rocks">Darkmira</a>'); } return new Response('Not found', 404); } } $kernel = new SfLiveKernel(); $request = Request::create('/blackfire'); $response = $kernel->handle($request, 1, false); // Essa chamada não captura exceções $response->send();
  20. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; public function handle(Request $request, $type = 1, $catch

    = true) { try { return $this->handleRaw($request); } catch (\Exception $e) { // rethrow ou manipular exception dependendo do $catch } } private function handleRaw(Request $request): Response { if ('/blackfire' === $request->getPathInfo()) { return new Response('<a href="https://blackfire.io">Blackfire</a>'); } else if ('/darkmira' === $request->getPathInfo()) { return new Response('<a href="https://php.darkmiratour.rocks">Darkmira</a>'); } throw new NotFoundHttpException('Not found'); }
  21. use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; public function handle(Request $request, $type = 1, $catch

    = true) { try { return $this->handleRaw($request); } catch (\Exception $e) { if (false === $catch) { throw $e; } return $this->handleException($e); } } private function handleException(\Exception $e): Response { $response = new Response($e->getMessage()); if ($e instanceof HttpExceptionInterface) { $response->headers->add($e->getHeaders()); return $response->setStatusCode($e->getStatusCode()); } return $response->setStatusCode(500); }
  22. use Symfony\Component\HttpFoundation\Request; $kernel = new SfLiveKernel(); $request = Request::create('/blackfire'); $response

    = $kernel->handle($request); // Agora essa chamada captura exceções $response->send();
  23. // ... $routes = [ // pathinfo => controller '/blackfire'

    => function (Request $request) { return new Response('<a href="https://blackfire.io">Blackfire</a>'); }, '/darkmira' => function (Request $request) { return new Response('<a href="https://php.darkmiratour.rocks">Darkmira</a>'); }, ]; // ...
  24. use Symfony\Component\EventDispatcher\Event; class RequestEvent extends Event { private $request; public

    function __construct(Request $request) { $this->request = $request; } public function getRequest(): Request { return $this->request; } }
  25. use Symfony\Component\EventDispatcher\EventSubscriberInterface; class RouterListener implements EventSubscriberInterface { protected $routes; public

    function __construct(array $routes = []) { $this->routes = $routes; } public static function getSubscribedEvents() { return ['kernel.request' => 'onKernelRequest']; } public function onKernelRequest(RequestEvent $event): void { $request = $event->getRequest(); foreach ($this->routes as $pathinfo => $controller) { if ($request->getPathInfo() === $pathinfo) { $request->attributes->add(['_controller' => $controller]); break; } } } }
  26. use Symfony\Component\EventDispatcher\EventDispatcherInterface; class SfLiveKernel implements HttpKernelInterface { protected $dispatcher; public

    function __construct(EventDispatcherInterface $dispatcher) { $this->dispatcher = $dispatcher; } // ... private function handleRaw(Request $request): Response { $event = new RequestEvent($request); $this->dispatcher->dispatch('kernel.request', $event); if (null === $controller = $request->attributes->get('_controller')) { throw new NotFoundHttpException('Not found'); } return $controller($request); } // ... }
  27. use Symfony\Component\EventDispatcher\EventDispatcher; $routes = [ '/blackfire' => function (Request $request)

    { return new Response('<a href="https://blackfire.io">Blackfire</a>'); }, '/darkmira' => function (Request $request) { return new Response('<a href="https://php.darkmiratour.rocks">Darkmira</a>'); }, ]; $dispatcher = new EventDispatcher(); // RouterListener::onKernelRequest será executado sempre em cada request e irá // fazer o roteamento para a controller através do atributo "_controller", desta forma // a controller pode ser vista e executada pelo SfLiveKernel::handleRaw $dispatcher->addSubscriber(new RouterListener($routes)); $kernel = new SfLiveKernel($dispatcher); $request = Request::create('/blackfire'); $response = $kernel->handle($request); $response->send();
  28. @hallboav • SymfonyConnect (próximos slides) • Badge & PDF (próximos

    slides) • Investimento 250 euros (~R$ 1.120,00 16 maio '19) • 40% desconto na black friday (novembro) • Symfony 3.0 e 4.0 • Níveis (Advanced e Expert) • Porcentagem de acertos • SensioLabs University (3 meses de workshop) Processo da certificação
  29. @hallboav Ainda sobre o processo da certificação • 75 questões,

    15 tópicos, 90 minutos (~1m15s/questão) • Pearson VUE ou exame online • Tipos de perguntas ◦ true/false, única resposta, respostas múltiplas • Validade voucher (um ano após a compra) • Retake (2x por ano e tem que pagar) • Não cai questões sobre bundles de terceiros ou Doctrine
  30. @hallboav Tópicos do exame • PHP and Web Security (11)

    ◦ Web security (XSS, CSRF, etc.) ◦ SPL (Std. PHP Lib.) • HTTP (9) ◦ Client / Server interaction ◦ Caching • Data Validation (7) ◦ PHP object validation ◦ Validation groups ◦ Violations builder • Dependency Injection (9) ◦ Service container ◦ Tags ◦ Services autowiring
  31. @hallboav Tópicos do exame • Symfony Architecture (13) ◦ Symfony

    Flex ◦ Configuration ◦ Event dispatcher ◦ Oficial best practices • Standardization (9) ◦ Naming conventions ◦ Coding standards • Security (11) ◦ Authentication ◦ Authorization ◦ Firewalls ◦ Guard ◦ Voters and voting strategies
  32. @hallboav Tópicos do exame • Controllers (12) ◦ The base

    controller class ◦ Internal redirects • Routing (11) ◦ Config. (YAML, XML, PHP & annotations) ◦ Generate URL parameters ◦ Special internal routing attributes • HTTP Caching (6) ◦ Expiration (Expires, Cache-Control) ◦ Validation (ETag, Last-Modified) ◦ Edge Side Includes • Console (8) ◦ Options and arguments ◦ Built-in helpers
  33. @hallboav Tópicos do exame • Templating with Twig (12) ◦

    Template inheritance ◦ Translations and pluralization • Forms (11) ◦ Form events ◦ CSRF protection ◦ Handling file upload • Automated Tests (10) ◦ Functional tests with PHPUnit ◦ PHPUnit Bridge • Miscellaneous (7) ◦ Process and Serializer components ◦ Internationalization and localization (Translation Component)
  34. @hallboav Benefícios • Promoção de cargo & aumento de salário

    • Visibilidade mundial (possibilidade de trabalhar no exterior) • Maior legitimidade em todo ecossistema, não apenas no Symfony • Desempate de perfis em momentos de contratação • Realização pessoal
  35. @hallboav Fake Certification (4.0) Verdadeiro ou falso: Para definir um

    serviço privado utilizamos "private: true"? 1. Verdadeiro 2. Falso
  36. @hallboav Fake Certification (4.0) Quais padrões de projeto o componente

    EventDispatcher implementa? 1. Mediator 2. Strategy 3. Adapter 4. Observer
  37. @hallboav Fake Certification (4.0) Responsável por limpar o cache do

    Symfony? 1. cache:clear 2. clear:cache 3. cache:clean 4. c:c
  38. @hallboav Fake Certification (4.0) Quais estratégias de decisão de acesso

    dos Voters existem? 1. affirmative 2. negative 2. concensus 3. unanimous
  39. @hallboav Mantenha-se atualizado • Siga o blog do Symfony (symfony.com/blog)

    • Siga pessoas que discutem Symfony no Twitter ◦ @SymfonyBrasil, @symfony, @nicolagrekas, @fabpot, @xabbuh, @TobiasSchultze, @Stof70, @weaverryan, @seldaek, @andreiabohner, @CyrilleGrandval, @jucycabrera, @KaFernandesDev, etc. • SymfonyBrasil no Telegram (https://t.me/SymfonyBrasil)