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

Develop Faster With FrankenPHP

Develop Faster With FrankenPHP

One of Symfony's strengths is its caching mechanism (the files stored in "var/cache"), which enables framework components such as the dependency injection container and the router, as well as numerous bundles, to be ultra-fast in production.

However, during development, regeneration of this cache can cause slowness and make the work of programmers tedious. Each time a PHP file, configuration file or Twig template is modified, all or part of the cache must be regenerated.

The latest version of FrankenPHP contains a new feature which, coupled with worker mode, can change all that: watchers.

After presenting how Symfony's caching mechanism works, and how to take advantage of it in our applications and bundles, we'll discover how to use watchers and FrankenPHP's worker mode to ensure that changes made to our code are reflected almost instantaneously in our browser, and thus avoid the frustration of long loading times in dev.

Kévin Dunglas

March 28, 2025
Tweet

More Decks by Kévin Dunglas

Other Decks in Programming

Transcript

  1. ➔ PHP API Platform creator, Symfony Core Team ➔ Go

    Mercure.rocks creator, Caddy maintainer, Go core contributor ➔ C PHP maintainer Kévin Dunglas: Polyglot Dev @[email protected] @dunglas.dev @dunglas
  2. Web and Cloud Experts ➔ Development (Symfony, Laravel, API Platform,

    JS, Go, Rust...) ➔ Support & hosting (FrankenPHP) apps ➔ Consultancy & maintenance ➔ UX & UI design ➔ [email protected] 💌
  3. Symfony’s Developer Experience ➔ Symfony is easy and pleasant to

    use ➔ It relies a lot on: • conventions: automatic service registration, autowiring, autoconfiguration… • User-friendly formats: attributes, YAML/PHP/XML config, Twig templates…
  4. The Cost of Developer Experience ➔ Parsing ➔ Compiling ➔

    Dumping ➔ Using the reflection API ➔ … ➔ Many computations ➔ Potentially low
  5. Alleviate The Cost ➔ Config: config files (YAML, XML…) are

    parsed, combined, converted in PHP and dumped ➔ DependencyInjection: the container is compiled and dumped for performance in production (uses Config under the hood) ➔ Routing (uses Config under the hood) ➔ Twig: templates are compiled in PHP files ➔ Cache: result of computations can be stored in cache
  6. ⚡ in Production: Symfony Apps Are Compiled ➔ The cache

    is populated 1 time, ideally at build time • bin/console cache:warmup ➔ Then it is reused for each request
  7. 🐢 in Dev ➔ Each time a file (PHP, Twig,

    YAML…) is touched… ➔ … the cache must be re-populated ➔ Populating the cache means writing files on disk (slow) ➔ On large projects (ex: Sylius), this can be very slow and hurts the DX
  8. FrankenPHP A modern app server for PHP apps: ➔ Replaces

    NGINX+FPM or Apache+mod_php ➔ Built for easy deployments: compatible with Docker, can embed your app in the binary! ➔ The fastest PHP engine ➔ 103 Early Hints support ➔ Built-in real-time support (Mercure) ➔ Compatible with all existing PHP apps: progressive enhancement
  9. ➔ Super simple to use: • Standalone binary (that can

    contain your app) • No external dependencies • Batteries included ➔ Built on top of the Caddy web server • All Caddy features and modules • Benefits from Go features • Extensible: in Go, in C, in PHP ➔ Designed for prod, CI and dev envs FrankenPHP: Modern PHP App Server
  10. FrankenPHP: Features BROTLI, ZSTANDARD & GZIP COMPRESSION Modern compression formats

    are supported out-of-the-box. STRUCTURED LOGGING Bring a more defined format and details to your logging. PROMETHEUS METRICS & TRACING Built-in Prometheus support! HTTP/2 & HTTP/3 Native support for HTTPS, HTTP/2 and HTTP/3. HTTPS AUTOMATION Automatic HTTPS certificate generation, renewal and revocation. GRACEFUL RELOAD Deploy your apps with zero downtime thanks to graceful reloads.
  11. ➔ Compatible with existing PHP apps (including Symfony, Laravel and

    even WordPress)! 🐘 ➔ Static binary ✨ ➔ Single Docker image 🐳 ➔ Entirely configurable 💅 • Caddyfile • php.ini ➔ Free software (as in free speech ✊, and free beer 🍺) FrankenPHP: At a Glance
  12. Getting Started With Static Binaries curl https://frankenphp.dev/install.sh | sh mv

    frankenphp /usr/local/bin/ frankenphp php-server -r public/
  13. Getting Started With Docker docker run -v $PWD:/app \ -p

    80:80 -p 443:443 -p 443:443/udp \ dunglas/frankenphp
  14. FrankenPHP Superpower: The Worker Mode ➔ Boot your application once

    ➔ Keep it in memory ➔ Process incoming requests without having to boot your app again ➔ Relies on goroutines and channels ➔ Somewhat similar to RoadRunner ➔ Unlike RoadRunner • runs in process: no network calls, no gRPC • uses plain old superglobals: no PSR-7
  15. FrankenPHP worker for Symfony # Install $ composer require \

    php-runtime/frankenphp-symfony # Run $ frankenphp \ -r public/ -w public/index.php
  16. Worker mode: Benchmark (Laravel Octane) 🧪 # Concurrency 1 for

    5 seconds… ./vendor/bin/pest stress http://127.0.0.1:8000 Swoole Medium Request Duration ........... 4.94 ms RoadRunner Medium Request Duration ....... 2.61 ms FrankenPHP Medium Request Duration ....... 0.88 ms # Concurrency 8 for 5 seconds… ./vendor/bin/pest stress http://127.0.0.1:8000 --concurrency=8 Swoole Medium Request Duration ........... 5.39 ms RoadRunner Medium Request Duration ....... 4.00 ms FrankenPHP Medium Request Duration ....... 1.59 ms Benchmark by Nuno Maduro (Laravel Core Team) using Pest’s stress testing plugin on a M1 pro.
  17. We Have A Problem ➔ Worker scripts are started at

    the same time as the web server ➔ They run forever ➔ If a file change (PHP file, Twig template, config…) • nothing happens • the worker script keeps running ➔ Worker mode is useless in dev
  18. Watchers ➔ FrankenPHP will watch files or directory for changes

    ➔ When a watcher file changes, the worker script is automatically restarted ➔ By default, typical Symfony files are watched: • PHP • YAML • Twig • .env
  19. Patterns Can Be Customized frankenphp { worker { file public/index.php

    watch /path/to/app watch /path/to/app/*.php watch /path/to/app/**/*.php watch /path/to/app/**/*.{php,twig} } }
  20. Worker In Dev Is Useful ➔ To render most web

    pages, browsers send several HTTP requests in parallel ➔ If these requests are handled by PHP (ex: JS, Turbo, React…), you’ll benefit from worker mode even in dev: the app will be hot
  21. Watchers And Symfony Cache Using the worker mode has another

    benefit: ➔ Symfony cache is refreshed instantly, in the background, when you save a file in your editor ➔ This dramatically reduces the time before the page is available ➔ Before: save ➡ refresh ➡ cache is building… ➔ After: save ➡ cache is building… ➡ refresh
  22. Meet our team and get FrankenPHP swag at our booth!

    Thank you! frankenphp.dev @dunglas Want to know more about how Les-Tilleuls.coop can help? ➔ Symfony development ➔ Support & hosting FrankenPHP apps ➔ Consultancy & maintenance ➔ UX & UI design