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

Build your framework like constructicons (PHP.F...

Build your framework like constructicons (PHP.FRL January 2017)

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, you'll learn how the total can be more than the sum of the parts, just like how Devastator was stronger than the individual Constructicons in Transformers.

Stefan Koopmanschap

January 24, 2017
Tweet

More Decks by Stefan Koopmanschap

Other Decks in Programming

Transcript

  1. SO WHY WOULD WE BUILD IT OURSELVES? > Custom needs

    > Because we're developers (NIH)
  2. SO WHY WOULD WE BUILD IT OURSELVES? > Custom needs

    > Because we're developers (NIH) > An open source framework is overkill
  3. SO WHY WOULD WE BUILD IT OURSELVES? > Custom needs

    > Because we're developers (NIH) > An open source framework is overkill > As a learning experience
  4. 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(); }); } );
  5. 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(); });
  6. 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(); });
  7. TEMPLATING $twigLoader = new Twig_Loader_Filesystem( __DIR__ . '/../views/' ); $twig

    = new Twig_Environment($twigLoader, [ 'cache' => '/tmp/twigCache', ]);
  8. 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(); });
  9. HANDLING CONFIGURATION $r->addRoute( 'GET', '/contact', function() use ($request, $twig) {

    $response = new Response( $twig->render('contact.twig', []) ); $response->send(); } );
  10. 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>
  11. 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( '[email protected]', 'An e-mail from the site', $mailbody ); $response = new \Symfony\Component\HttpFoundation\RedirectResponse('/hello'); $response->send(); } );
  12. HANDLING CONFIGURATION $configProvider = new \werx\Config\Providers\JsonProvider( __DIR__ . '/../config/' );

    $config = new \werx\Config\Container($configProvider); $config->load('config');
  13. 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);
  14. 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(), ])); });
  15. SUMMARY > valid use cases for building your own framework

    > Leverage the power of open source components and composer
  16. 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
  17. SOME OTHER COMPONENTS YOU COULD THINK OF > DI (bitexpert/disco,

    symfony/dependency-injection, league/container)
  18. SOME OTHER COMPONENTS YOU COULD THINK OF > DI (bitexpert/disco,

    symfony/dependency-injection, league/container) > Console (symfony/console, illuminate/console, webmozart/console)
  19. 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)
  20. 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)