Build Your Framework Like Constructicons - 010PHP

Build Your Framework Like Constructicons - 010PHP

While we have a strong offering of full-stack frameworks and microframeworks, the rise of components and libraries combined with Composer allows us to easily build our own framework without reinventing the wheel. In this talk, I'll show you how the total can be more than the sum of the parts, such as Devastator was stronger than the individual Constructicons in Transformers.

A8f72e32766355f12a56ede9aaa0ee78?s=128

Stefan Koopmanschap

May 11, 2017
Tweet

Transcript

  1. 1.
  2. 7.
  3. 8.
  4. 9.
  5. 10.
  6. 11.
  7. 14.
  8. 16.
  9. 18.
  10. 19.
  11. 23.

    SO WHY WOULD WE BUILD IT OURSELVES? > Custom needs

    > Because we're developers (NIH)
  12. 24.

    SO WHY WOULD WE BUILD IT OURSELVES? > Custom needs

    > Because we're developers (NIH) > An open source framework is overkill
  13. 25.

    SO WHY WOULD WE BUILD IT OURSELVES? > Custom needs

    > Because we're developers (NIH) > An open source framework is overkill > As a learning experience
  14. 30.
  15. 32.
  16. 33.
  17. 34.
  18. 36.
  19. 41.
  20. 43.

    COMPOSER INIT { "name": "stefankoopmanschap/constructicons", "authors": [ { "name": "Stefan

    Koopmanschap", "email": "stefan@ingewikkeld.net" } ], "require": {} }
  21. 53.
  22. 54.
  23. 60.

    ROUTING $dispatcher = FastRoute\simpleDispatcher( function(FastRoute\RouteCollector $r) use ($request) { $r->addRoute('GET',

    '/hello', function() use ($request) { $response = new Response( 'Hello ' . $request->get('name', 'world') ); $response->send(); }); $r->addRoute('GET', '/goodbye', function() use ($request) { $response = new Response( 'Goodbye ' . $request->get('name', 'world') ); $response->send(); }); } );
  24. 62.

    ROUTING $r->addRoute('GET', '/hello', function() use ($request) { $response = new

    Response( 'Hello ' . $request->get('name', 'world') ); $response->send(); }); $r->addRoute('GET', '/goodbye', function() use ($request) { $response = new Response( 'Goodbye ' . $request->get('name', 'world') ); $response->send(); });
  25. 64.

    ROUTING $r->addRoute('GET', '/hello[/{name}]', function($params) use ($request) { $name = $params['name']

    ?? 'world'; $response = new Response( 'Hello ' . $name ); $response->send(); }); $r->addRoute('GET', '/goodbye[/{name}]', function() use ($request) { $name = $params['name'] ?? 'world'; $response = new Response( 'Goodbye ' . $name ); $response->send(); });
  26. 66.
  27. 72.

    TEMPLATING $twigLoader = new Twig_Loader_Filesystem( __DIR__ . '/../views/' ); $twig

    = new Twig_Environment($twigLoader, [ 'cache' => '/tmp/twigCache', ]);
  28. 74.

    TEMPLATING $r->addRoute( 'GET', '/hello[/{name}]', function($params) use ($request, $twig) { $name

    = $params['name'] ?? 'world'; $response = new Response( $twig->render('hello.twig', [ 'name' => $name ] ) ); $response->send(); });
  29. 81.

    HANDLING CONFIGURATION $r->addRoute( 'GET', '/contact', function() use ($request, $twig) {

    $response = new Response( $twig->render('contact.twig', []) ); $response->send(); } );
  30. 82.

    HANDLING CONFIGURATION <form method="post" action="/contact"> Your name: <input type="name" /><br

    /> Your e-mailaddress: <input type="email" /><br /> Your message:<br /> <textarea></textarea><br /> <input type="submit" name="submit" value="Contact Us" /> </form>
  31. 83.

    HANDLING CONFIGURATION $r->addRoute( 'POST', '/contact', function() use ($request, $twig) {

    $mailbody = 'An e-mail was sent through the site with the following message: ' . $request->get('message') . "\n"; $mailbody .= 'Sent by: ' . $request->get('name') . '<' . $request->get('email') . '>'; mail( 'my-email@example.org', 'An e-mail from the site', $mailbody ); $response = new \Symfony\Component\HttpFoundation\RedirectResponse('/hello'); $response->send(); } );
  32. 85.

    HANDLING CONFIGURATION $configProvider = new \werx\Config\Providers\JsonProvider( __DIR__ . '/../config/' );

    $config = new \werx\Config\Container($configProvider); $config->load('config');
  33. 94.

    SENDING E-MAIL $message = Swift_Message::newInstance('An e-mail from the site') ->setFrom([

    $request->get('email'), $request->get('name')] ) ->setTo([ $config->get('contact_email') ]) ->setBody('An e-mail was sent through the site with the following message: ' . $request->get('message')) ; $mailer->send($message);
  34. 101.

    DOING VALIDATION $r->addRoute( 'POST', '/contact', function() use ($request, $config, $mailer,

    $contactMailValidator, $twig) { $result = $contactMailValidator->validate([ 'name' => $request->get('name'), 'email' => $request->get('email'), 'message' => $request->get('message') ]); if ($result->isValid()) { // send e-mail and redirect } return new Response($twig->render('contact.twig', [ 'errors' => $result->getMessages(), ])); });
  35. 102.
  36. 104.

    SUMMARY > valid use cases for building your own framework

    > Leverage the power of open source components and composer
  37. 105.

    SUMMARY > valid use cases for building your own framework

    > Leverage the power of open source components and composer > Only need a few lines of glue
  38. 107.

    SOME OTHER COMPONENTS YOU COULD THINK OF > DI (bitexpert/disco,

    symfony/dependency-injection, league/container)
  39. 108.

    SOME OTHER COMPONENTS YOU COULD THINK OF > DI (bitexpert/disco,

    symfony/dependency-injection, league/container) > Console (symfony/console, illuminate/console, webmozart/console)
  40. 109.

    SOME OTHER COMPONENTS YOU COULD THINK OF > DI (bitexpert/disco,

    symfony/dependency-injection, league/container) > Console (symfony/console, illuminate/console, webmozart/console) > http requests (Guzzle)
  41. 110.

    SOME OTHER COMPONENTS YOU COULD THINK OF > DI (bitexpert/disco,

    symfony/dependency-injection, league/container) > Console (symfony/console, illuminate/console, webmozart/console) > http requests (Guzzle) > logging (monolog/monolog)
  42. 111.
  43. 114.