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

FrankenPHP: A modern app server for PHP, written in Go

FrankenPHP: A modern app server for PHP, written in Go

https://frankenphp.dev

A new app server and a library to embed PHP in Go.

* Easy to Dockerize
* Early Hints Support
* Worker mode for performance
* Real-time with the built-in Mercure hub
* Symfony integration (Laravel coming soon)

Kévin Dunglas

October 14, 2022
Tweet

More Decks by Kévin Dunglas

Other Decks in Programming

Transcript

  1. ➔ PHP API Platform creator, Symfony maintainer ➔ GO Go

    core contributor, Mercure.rocks and Vulcain.rocks creator ➔ C PHP core contributor Kévin Dunglas: Polyglot Dev @dunglas
  2. FrankenPHP A modern app server for PHP ➔ Built for

    containers ➔ Worker mode ➔ 103 Early Hints support ➔ Real-time support (Mercure module) ➔ Compatible with all existing PHP apps: ◆ progressive enhancement
  3. Containers: Which SAPI? Server Application Programming Interface: interface between the

    PHP interpreter and web servers ➔ Apache module ➔ FPM (FastCGI Process Manager) ➔ CGI (Common Gateway Interface) ➔ NGINX Unit (not the NGINX you’re used to) ➔ …
  4. ➔ Simple ➔ Web server + PHP = 1 service

    ➔ Default solution for containers DRAWBACKS: ➔ Works only with Apache ➔ Less performant than FPM Apache Module
  5. FPM ➔ Most popular SAPI ➔ Supported by most web

    servers: Caddy, Symfony CLI, NGINX, Apache… DRAWBACKS: ➔ External service ➔ Require a UNIX or a TCP socket ➔ Hard to containerize
  6. ➔ Secure and fast ➔ Easy to configure ➔ Cloud

    native: API, hot config reloading… ➔ Automatic HTTPS ➔ HTTP/2, HTTP/3, Early Hints… ➔ Extensible with modules: Mercure, Vulcain, OAuth, OIDC… ➔ Prod ready ➔ Written in Go 😻 Caddy: The New Kid on the Block
  7. ➔ Perfect for containers ◆ Just 1 service ◆ No

    external dependencies ➔ Built on top of Caddy ◆ All Caddy features and modules ◆ Benefits from Go features ◆ Extensible: in Go, in C, in PHP ➔ Prod, CI and dev FrankenPHP: Modern PHP App Server
  8. ➔ Standalone Go library ➔ Embed PHP in your Go

    programs ➔ New SAPI for Go net/http ◆ Caddy, Symfony CLI, Traefik, K8S… ◆ Your custom Go app ➔ Caddy module using the library ➔ Unique features The ❤ of FrankenPHP: A New SAPI For Go
  9. ➔ Compatible with existing PHP apps! ➔ 1 service, 1

    container image 😍 ➔ Also works without Docker ➔ Entirely configurable ◆ Caddyfile ◆ php.ini ➔ Free software (as in free speech ✊, and free beer 🍺) FrankenPHP: At a Glance
  10. 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 ➔ Compatible with Symfony Runtime and Laravel Octane (soon) ➔ Somewhat similar to RoadRunner ➔ Unlike RR, uses plain old superglobals
  11. FrankenPHP: Worker Benchmark 🧪 ➔ Setup: ◆ Hello World Symfony

    app (prod mode) ◆ Caddy Web Server (HTTP/2) ◆ 3000 requests, 100 connected users ◆ Benchmark tool: K6 ➔ Average request duration: ◆ FPM: 9.45ms ◆ FrankenPHP (no worker): 12.72ms ◆ FrankenPHP (worker): 2.53ms
  12. ➔ PHP scripts are interpreted ➔ The PHP interpreter is

    written in C ➔ php-src uses Zend Engine ◆ compiler (with Just In Time) ◆ executor (Virtual Machine) ➔ SAPIs ◆ Pass input from the web server to the PHP engine ◆ Pass output from the the PHP engine to the web server PHP Internals: the Basics
  13. PHP as a C Library ➔ PHP can be used

    by C programs as a library ◆ It’s how the Apache module works ➔ The embed SAPI eases the process for simple cases ➔ The library can be linked ◆ dynamically (.so) ◆ statically
  14. ➔ Go is a compiled language ➔ Go programs can

    call C code ➔ Go and C files can be compiled in a single program ➔ The resulting binary can be static! ➔ The native package to call C code is called cgo ➔ Using cgo we can embed PHP in Caddy, Symfony CLI and other Go programs! C? Go? Cgo!
  15. ➔ Go is especially convenient to build servers and network

    apps ➔ net/http: native package to create HTTP clients and servers ➔ Production-grade: optimized and secure ➔ Native HTTP/2 (HTTP/3 with a 3rd party lib) ➔ Used by Caddy, Symfony CLI, Kubernetes, Traefik, Google, Cloudflare… net/http
  16. A PHP SAPI for Go net/http ➔ SAPI: bridge between

    a server and the PHP engine ➔ Use cgo to call PHP with data coming from Go’s HTTP messages ➔ Extract data from Go’s http.Request, pass it to PHP ➔ Write data generated by PHP using Go’s http.ResponseWriter
  17. ➔ net/http is based on the flagship feature of Go:

    goroutines ➔ Goroutines are lightweight threads ➔ Goroutines are executed concurrently ➔ Goroutines can run in parallel on different CPUs ➔ Go provides user-friendly synchronization mechanisms (channels) Goroutines
  18. PHP Process-based Model (non-ZTS) 1 PHP process handles only 1

    request concurrently. To handle requests simultaneously, start new OS processes. Model of FPM and CLI.
  19. ➔ Goroutines are lightweight threads: a mix of real parallelism

    (system threads) and asynchronous I/O ➔ Several goroutines share the same OS thread ➔ Goroutines are lighter and faster than OS threads… ➔ …but ZTS isn’t enough to ensure PHP memory safety 😱 PHP must run in its own threads! Goroutines Aren’t OS Threads
  20. ➔ 🧪 Still highly experimental! ➔ Fix the remaining segfaults

    issues ➔ Test, test and test again ➔ Add support to Laravel Octane ➔ Use it in Symfony CLI ➔ Add Windows support ➔ Contributions welcome! What’s next?!