Slide 1

Slide 1 text

And PHP came back from the dead! https://frankenphp.dev

Slide 2

Slide 2 text

➔ PHP API Platform creator, Symfony Core Team, Occasional Laravel contributor ➔ Go Mercure.rocks creator, Caddy maintainer, Go core contributor ➔ C PHP core contributor Kévin Dunglas: Polyglot Dev @dunglas

Slide 3

Slide 3 text

Web and Cloud Experts ➔ Web development (PHP, JS, Go, Rust...) ➔ Support & hosting (FrankenPHP) apps ➔ Consultancy & maintenance ➔ UX & UI design ➔ [email protected] 💌

Slide 4

Slide 4 text

FRANKENPHP?!

Slide 5

Slide 5 text

FrankenPHP A modern app server for Laravel and PHP apps: ➔ Replaces NGINX+FPM or Apache+mod_php ➔ Built for easy deployments: compatible with Forge and Docker, can embed your app in the binary! ➔ The fastest Laravel Octane engine ➔ 103 Early Hints support ➔ Built-in Laravel Broadcast support (Mercure) ➔ Compatible with all existing PHP apps: progressive enhancement

Slide 6

Slide 6 text

➔ 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

Slide 7

Slide 7 text

➔ Standalone Go library: calls libphp (the official PHP engine as a C library) using cgo ➔ Embed PHP in any Go program (static build) ➔ New SAPI for Go net/http ◆ Caddy, Traefik, Kubernetes… ◆ Your custom Go app ➔ Caddy module using the library ➔ Unique features The ❤ of FrankenPHP

Slide 8

Slide 8 text

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.

Slide 9

Slide 9 text

➔ Compatible with existing PHP apps (including Laravel, Symfony 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

Slide 10

Slide 10 text

Getting Started

Slide 11

Slide 11 text

Using Docker

Slide 12

Slide 12 text

FRANKENPHP FOR OCTANE

Slide 13

Slide 13 text

FrankenPHP Superpower: The Worker Mode ➔ A new engine for Laravel Octane ➔ 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

Slide 14

Slide 14 text

FrankenPHP for Octane # Install $ composer require laravel/octane $ php artisan octane:install \ --server=frankenphp # Run $ php artisan octane:start

Slide 15

Slide 15 text

FrankenPHP for Octane: HTTPS # Generates (and renew) a TLS certificate # Starts an HTTPS server # supporting HTTP/1, HTTP/2, HTTP/3 # and Early Hints php artisan octane:start \ --host=example.com \ --port=443 \ --admin-port=2019

Slide 16

Slide 16 text

FrankenPHP for Octane: Benchmark 🧪 # 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 using Pest’s stress testing plugin on a M1 pro.

Slide 17

Slide 17 text

103 EARLY HINTS

Slide 18

Slide 18 text

103 Early Hints

Slide 19

Slide 19 text

Typical Web Page © Google

Slide 20

Slide 20 text

103 Early Hints © Google ~30% LCP improvement 🚀

Slide 21

Slide 21 text

Early Hints: Not Possible With PHP

Slide 22

Slide 22 text

Early Hints: Possible With Go 👋

Slide 23

Slide 23 text

Early Hints: Supported by FrankenPHP ⚡ header('Link: ; rel=preload; as=style'); headers_send(103); // Your slow algorithms and SQL queries 🤪 echo <<<'HTML' Hello FrankenPHP HTML;

Slide 24

Slide 24 text

Early Hints: Laravel + FrankenPHP ⚡ Route::get('/', function () { $r = new Response(); $r->headers->set('Link', '; rel=preload; as=style'); $r->sendHeaders(103); // Your slow algorithms and SQL queries 🤪 $r->setContent('The result of your computations'); return $r; });

Slide 25

Slide 25 text

Mercure and Laravel Broadcast

Slide 26

Slide 26 text

Mercure: Alternative To WebSockets

Slide 27

Slide 27 text

FrankenPHP: Built-In Mercure Hub

Slide 28

Slide 28 text

Octane: Enable The Mercure Hub // config/octane.php return [ // ... 'mercure'=> [ 'publisher_jwt' => 'MySecret', 'subscriber_jwt' => 'MySecret', 'anonymous' => true, ], ];

Slide 29

Slide 29 text

Broadcasting: Add The Mercure Provider // composer require mvanduijker/laravel-mercure-broadcaster // config/broadcasting.php return [ 'default' => 'mercure', 'connections' => [ 'mercure' => [ 'driver' => 'mercure', 'url' => 'http://127.0.0.1:8000/.well-known/mercure', 'secret' => 'MySecret', ], ] ];

Slide 30

Slide 30 text

Broadcasting: Create an Event namespace App\Events; use Duijker\LaravelMercureBroadcaster\Broadcasting\Channel; use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow; class ThingDone implements ShouldBroadcastNow { public function __construct(public string $foo) {} public function broadcastOn(): Channel { return new Channel('things_done'); } }

Slide 31

Slide 31 text

Broadcasting: Subscribe and Dispatch // Subscribe in the browser, no 3rd-party lib required! // Compatible with Livewire and all JS frameworks const eventSource = new EventSource( '/.well-known/mercure?topic=things_done' ); eventSource.onmessage = e => console.log(e); // From Laravel: broadcast the event event(new ThingDone('foo'));

Slide 32

Slide 32 text

Package Your Apps As a Standalone Binary

Slide 33

Slide 33 text

A standalone Laravel App: We’ll create a static binary containing: ➔ A web server (Caddy) ➔ PHP (and its dependencies) ➔ The extensions we need (and their dependencies) ➔ FrankenPHP ➔ Our Laravel and PHP app ➔ The dependencies of our Laravel app ➔ Our assets

Slide 34

Slide 34 text

Laravel App As a Standalone Binary # Prepare your app $ composer install --no-dev -a $ php artisan [config|event|route]:cache # Build $ git clone https://github.com/dunglas/frankenphp && cd frankenphp $ EMBED=/path/to/my/laravel/app ./build-static.sh # Run in standard mode 🎉 $ ./dist/frankenphp-- php-server # Run with Octane 🎉🎉🎉 $ ./dist/frankenphp-- php-cli artisan octane:start

Slide 35

Slide 35 text

Meet our team and get FrankenPHP swag (or a beer) at our booth! Thanks! frankenphp.dev @dunglas Want to know more about FrankenPHP or how Les-Tilleuls.coop can help you?