symfony without frameworkbundle€¦ · @tobiasnyholm tobias nyholm • full stack unicorn on...

78
@tobiasnyholm Symfony without FrameworkBundle Tobias Nyholm https://joind.in/talk/f2ecf

Upload: others

Post on 06-Jul-2020

38 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Symfony without FrameworkBundle

Tobias Nyholm

https://joind.in/talk/f2ecf

Page 2: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Why?

Page 3: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Tobias Nyholm• Full stack unicorn on Happyr.com

• Certified Symfony developer

• Symfony core member

• Symfony CARE

• PHP-Stockholm

• Open source

Page 4: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Open source

PHP-cache

HTTPlug

Mailgun

LinkedIn API clientSwap

Stampie

BazingaGeocoderBundle

PHP-Geocoder

FriendsOfApi/boilerplateGuzzle Buzz

CacheBundlePSR7

SymfonyBundleTest

NSA

SimpleBus integrations

PSR HTTP clients

Neo4j

KNP Github API

PHP-Translation

Puli

Assert

Backup-manager/symfony

php-http/httplug-bundle php-http/multipart-stream

php-http/discovery

happyr/normal-distribution-bundle

nyholm/effective-interest-rate

MailgunBundle

league/geotools

NewRelicBundle

Page 5: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

“Frameworks are slow”

Page 6: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

areFrameworks slow

??? = Poor performance

Page 7: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

What is a framework?

Page 8: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

What is a framework?Symfony

Page 9: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

svn checkout http://svn.symfony-project.com/tags/RELEASE_1_4_8 symfony

“Symfony folder”

Page 10: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

composer create-project symfony/framework-standard-edition acme "2.8.*"

“vendor/symfony/symfony”

Page 11: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

composer create-project symfony/framework-standard-edition acme “3.4.*”

“vendor/symfony/symfony”

Page 12: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

composer create-project symfony/skeleton acme

“vendor/symfony/*”

Page 13: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

{ "name": "symfony/skeleton", "require": { "php": "^7.1.3", "ext-ctype": "*", "ext-iconv": "*", "symfony/console": "*", "symfony/flex": "^1.1", "symfony/framework-bundle": "*", "symfony/yaml": "*" }, "require-dev": { "symfony/dotenv": "*" } }

Page 14: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

What is a framework?Symfony

Page 15: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

{ "name": "symfony/framework-bundle", "type": "symfony-bundle", "description": "Symfony FrameworkBundle", "require": { "php": "^7.1.3", "ext-xml": "*", "symfony/cache": "~3.4|~4.0", "symfony/dependency-injection": "^4.2", "symfony/config": "~4.2", "symfony/event-dispatcher": "^4.1", "symfony/http-foundation": "^4.1.2", "symfony/http-kernel": "^4.2", "symfony/polyfill-mbstring": "~1.0", "symfony/filesystem": "~3.4|~4.0", "symfony/finder": "~3.4|~4.0", "symfony/routing": "^4.1" } }

Page 16: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •
Page 17: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Level of Magic

0 %10 %20 %30 %40 %50 %60 %70 %80 %90 %

100 %

Symfony version

1 2 3 4 5

Awesome

User responsibillity

Magic

Page 18: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

an ecosystemwhatever we makeSymfony is a community

Page 19: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •
Page 20: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

(pause for tweeting)

#Symfony_Live

Page 21: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

areFrameworks slow

Our code = Poor performance

Page 22: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Let’s talk about performance

Page 23: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Rule 1: Buy a better server

Page 24: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Rule 2: Use Varnish

Page 25: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Req

uest

s p

er t

ime

unit

0

1000

2000

3000

4000

No Varnish With Varnish

Page 26: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Rule 3: Run less code

Page 27: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

section .text global _start ; must be declared for linker (ld)

_start: ; tell linker entry point

mov edx,len ; message length mov ecx,msg ; message to write mov ebx,1 ; file descriptor (stdout) mov eax,4 ; system call number (sys_write) int 0x80 ; call kernel

mov eax,1 ; system call number (sys_exit) int 0x80 ; call kernel

section .data

msg db 'Hello, world!',0xa ; our dear string len equ $ - msg ; length of our dear string

Page 28: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

More code = More “ticks”

Page 29: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Version Lines of codeLines

executedFunction calls Memory Time

Symfony 1.4 172 000 2 401 10 588 1 200 Kb 198 ms

Symfony 2.8 415 700 1 928 5 051 1 600 Kb 100 ms

Symfony 3.4 433 600 2 649 4 004 1 600 Kb 82 ms

Symfony 4.1 136 000 1 029 1 421 500 Kb 31 ms

Hello world

Page 30: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Fastest application

<?php // index.php

if (isset($_GET['page']) && $_GET['page'] === 'foo') { echo "Foo page <br>"; } else { echo "Welcome to index! <br>"; }

Page 31: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

What is your application doing?

Page 32: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

<?php

$uri = $_SERVER['REQUEST_URI']; $base = 'https://happyr.com';

if (substr($uri, 0, 1) !== 'j') { redirect($base); }

redirect(sprintf('%s/x/job/%d-x_x', $base, substr($uri, 1)));

function redirect($url) { header('Location: '.$url); exit(0); }

Page 33: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Complexity

Redirect symfony/skeleton symfony/website-skeleton

Your application?

Page 34: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Do you need this?

Page 35: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Do you need this?

Forms

Security

Validation

Router

Dependency injectionEvent dispatcher

Serializer

Yaml Translation

HTTP KernelHTTP Foundation

FinderDebug

Page 36: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Do we need HTTP?

Page 37: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

HTTP Foundation

$_SERVER[‘REQUEST_URI’]

vs

Page 38: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Messenger component?

Page 39: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Doctrine or just PDO?

Page 40: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Building a small application

Page 41: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Workflow component

Page 42: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

<?php

use Symfony\Component\Workflow\DefinitionBuilder; use Symfony\Component\Workflow\Transition; use Symfony\Component\Workflow\Workflow; use Symfony\Component\Workflow\MarkingStore\SingleStateMarkingStore;

$definitionBuilder = new DefinitionBuilder(); $definition = $definitionBuilder->addPlaces(['draft', 'review', 'rejected', 'published']) ->addTransition(new Transition('to_review', 'draft', 'review')) ->addTransition(new Transition('publish', 'review', 'published')) ->addTransition(new Transition('reject', 'review', 'rejected')) ->build() ;

$marking = new SingleStateMarkingStore('currentState'); $workflow = new Workflow($definition, $marking);

$article = /* fetch from database */ if ($workflow->can($article, 'publish')) { $workflow->apply($article, 'publish');

// TODO redirect or any other action ... }

Page 43: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Cache component

Page 44: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

namespace Symfony\Contracts\Cache;

/** * Gets/Stores items from/to a cache. * * On cache misses, a callback is called that should return the missing value. * This callback is given an ItemInterface object corresponding to the needed key, * that could be used e.g. for expiration control. */ interface CacheInterface { /** * @param callable(ItemInterface) $callback Should return the computed value for the given * key/item * @param float|null $beta A float that, as it grows, controls the likeliness * of triggering early expiration. 0 disables it, * INF forces immediate expiration. * * @return mixed The value corresponding to the provided key * * @throws InvalidArgumentException When $key is not valid or when $beta is negative */ public function get(string $key, callable $callback, float $beta = null); }

Page 45: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

$result = $cache->get('foobar', function (ItemInterface $item) { $pi = null; /* Calculation of pi */ $item->expiresAfter(3600);

return $pi; });

Page 46: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

$result = $cache->get('foobar', function (ItemInterface $item) { $pi = null; /* Calculation of pi */ $item->expiresAfter(3600);

return $pi; });

Time

T: 0 T: 3600

Page 47: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Middleware pattern

Page 48: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

<?php

use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request; use App\Runner;

require __DIR__.'/../vendor/autoload.php';

$request = Request::createFromGlobals(); $response = new Response();

$middleware[] = function(Request $request, Response $response, callable $next) { if ($request->getMethod() !== 'GET') { return new Response('Method not allowed', 405); } return $next($request, $response); };

$middleware[] = function(Request $request, Response $response, callable $next) { $response->setContent('foobar'); return $next($response, $response); };

$runner = new Runner($middleware); $response = $runner($request, $response);

// Send response echo $response->getBody();

Page 49: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

namespace App;

use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request;

class Runner { /** @var callable[] */ private $queue;

public function __construct(array $queue) { $this->queue = $queue; }

public function __invoke(Request $request, Response $response) { $middleware = array_shift($this->queue); if (null === $middleware) { // Default return function (Request $request, Response $response, callable $next) { return $response; }; }

return $middleware($request, $response, $this); } }

Page 50: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

<?php

namespace App\Middleware;

use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request;

interface MiddlewareInterface { public function __invoke(Request $request, Response $response, callable $next); }

Page 51: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

namespace App\Middleware;

use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request;

class Router implements MiddlewareInterface { public function __invoke(Request $request, Response $response, callable $next) { $uri = $request->getUri();

switch ($uri) { case '/': $response = (new \App\Controller\StartpageController())->run($request); break; case '/foo': $response = (new \App\Controller\FooController())->run($request); break; default: $response->setStatusCode(404); $response->setContent('Not Found'); break; }

return $next($request, $response); } }

Page 52: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

<?php

use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request; use App\Runner;

require __DIR__.'/../vendor/autoload.php';

$request = Request::createFromGlobals(); $response = new Response();

$middleware[] = new Cache; $middleware[] = new NewRelic; $middleware[] = new Security; $middleware[] = new Router;

$runner = new Runner($middleware); $response = $runner($request, $response);

// Send response echo $response->getBody();

Page 53: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Custom kernel

Page 54: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Dumper\PhpDumper; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

class Kernel { private $booted = false; private $debug; private $env;

/** @var Container */ private $container;

public function __construct(string $env, bool $debug = false) { $this->debug = $debug; $this->env = $env; }

/** * Handle a Request and turn it in to a response. */ public function handle(Request $request): Response { $this->boot();

Page 55: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •
Page 56: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

require_once $containerDumpFile; $container = new \CachedContainer(); } else { $container = new ContainerBuilder(); $container->setParameter('kernel.project_dir', $this->getProjectDir()); $container->setParameter('kernel.environment', $this->env);

$container->registerForAutoconfiguration(EventSubscriberInterface::class) ->addTag('kernel.event_subscriber');

$container->registerForAutoconfiguration(Command::class) ->addTag('console.command');

$container->addCompilerPass(new AddConsoleCommandPass()); $container->addCompilerPass( new RegisterListenersPass(EventDispatcherInterface::class), PassConfig::TYPE_BEFORE_REMOVING );

$fileLocator = new FileLocator($this->getProjectDir().'/config'); $loader = new YamlFileLoader($container, $fileLocator); try { $loader->load('services.yaml'); $loader->load('services_'.$this->env.'.yaml'); } catch (FileLocatorFileNotFoundException $e) { }

$container->compile();

//dump the container @mkdir(dirname($containerDumpFile), 0777, true);

Page 57: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Too much boilerplate?Use the FrameworkBundle

Page 58: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Kernel as BaseKernel; use Symfony\Component\Routing\RouteCollectionBuilder;

class Kernel extends BaseKernel { use MicroKernelTrait;

public function registerBundles() { return [ new FrameworkBundle(), ]; }

protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader) { $confDir = $this->getProjectDir().'/config'; $loader->load($confDir.'/services.yaml'); $loader->load($confDir.'/services_'.$this->environment.'.yaml'); }

protected function configureRoutes(RouteCollectionBuilder $routes) { $confDir = $this->getProjectDir().'/config'; $routes->import($confDir.'/routes.yaml');

Page 59: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Kernel as BaseKernel; use Symfony\Component\Routing\RouteCollectionBuilder;

class Kernel extends BaseKernel { use MicroKernelTrait;

public function registerBundles() { return [ new FrameworkBundle(), ]; }

protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader) { $confDir = $this->getProjectDir().'/config'; $loader->load($confDir.'/services.yaml'); $loader->load($confDir.'/services_'.$this->environment.'.yaml'); }

protected function configureRoutes(RouteCollectionBuilder $routes) { $confDir = $this->getProjectDir().'/config'; $routes->import($confDir.'/routes.yaml');

Page 60: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

/** * A Kernel that provides configuration hooks. * * @author Ryan Weaver <[email protected]> * @author Fabien Potencier <[email protected]> */ trait MicroKernelTrait { abstract protected function configureRoutes(RouteCollectionBuilder $routes); abstract protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader);

public function registerContainerConfiguration(LoaderInterface $loader) { $loader->load(function (ContainerBuilder $container) use ($loader) { $container->loadFromExtension('framework', array( 'router' => array( 'resource' => 'kernel::loadRoutes', 'type' => 'service', ), ));

if ($this instanceof EventSubscriberInterface) { $container->register('kernel', static::class) ->setSynthetic(true) ->setPublic(true) ->addTag('kernel.event_subscriber') ; }

Page 61: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Improve performance

Page 62: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Improve performance

#1: Buy a better server

#2: Use Varnish

#3: Run less code

Page 63: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Improve performance

#1: Buy a better computer

#2: Use cache

#3: Run less code

Page 64: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Profile your application

Page 65: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •
Page 66: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •
Page 67: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •
Page 68: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

“Normal” PHP-FPM

App

App

App

App

HTTP FastCGI

Page 69: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

PHPFastCGI

App

App

App

App

HTTP FastC

GI

https://github.com/PHPFastCGI/FastCGIDaemon

Page 70: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

<?php

require_once dirname(__FILE__) . '/../vendor/autoload.php';

use PHPFastCGI\FastCGIDaemon\ApplicationFactory; use PHPFastCGI\FastCGIDaemon\Http\RequestInterface; use Symfony\Component\HttpFoundation\Response;

$kernel = function (RequestInterface $request) { $sfRequest = $request->getHttpFoundationRequest();

return new Response('<h1>Hello, World!</h1>' . $sfRequest->getUri()); };

$application = (new ApplicationFactory)->createApplication($kernel); $application->run();

https://github.com/PHPFastCGI/FastCGIDaemon

Page 71: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

<?php

require_once dirname(__FILE__) . '/../vendor/autoload.php';

use PHPFastCGI\FastCGIDaemon\ApplicationFactory; use PHPFastCGI\FastCGIDaemon\Http\RequestInterface; use Symfony\Component\HttpFoundation\Response;

$kernel = function (RequestInterface $request) { $sfRequest = $request->getHttpFoundationRequest();

$response = new Response();

$middleware[] = new Cache; $middleware[] = new NewRelic; $middleware[] = new Security; $middleware[] = new Router;

$runner = new Runner($middleware); $response = $runner($sfRequest, $response);

return $response; };

$application = (new ApplicationFactory)->createApplication($kernel); $application->run();

Page 72: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

use PHPFastCGI\FastCGIDaemon\Http\RequestInterface; use PHPFastCGI\FastCGIDaemon\KernelInterface as PHPFastCGIKernel; use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\HttpKernel\TerminableInterface;

class FastCGIKernel implements PHPFastCGIKernel { private $kernel;

public function __construct(KernelInterface $kernel) { $this->kernel = $kernel; }

public function handleRequest(RequestInterface $request) { $this->kernel->boot();

$symfonyRequest = $request->getHttpFoundationRequest(); $symfonyResponse = $this->kernel->handle($symfonyRequest);

if ($this->kernel instanceof TerminableInterface) { $this->kernel->terminate($symfonyRequest, $symfonyResponse); }

return $symfonyResponse; } }

Page 73: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

< 10ms

Page 74: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

< 5ms

Page 75: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Page 76: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

Remember

Page 77: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •

@tobiasnyholm

– Tobias Nyholm

“We are Symfony”

https://joind.in/talk/f2ecf

Page 78: Symfony without FrameworkBundle€¦ · @tobiasnyholm Tobias Nyholm • Full stack unicorn on Happyr.com • Certified Symfony developer • Symfony core member • Symfony CARE •