FrankenPHPとは何か
「サーバーとは何かを理解して、コンテナ1つで実行しよう | PHPerKaigi2024」 というスライドで FrankenPHP の話が出ており、以前から気になっていたので軽く調べてみました。
FrankenPHPとは
FrankenPHPとは簡単にいうとPHPを実行可能なWebサーバーです。公式サイトには次のように説明されています。
The Modern PHP App Server, written in Go
しかしこの説明だと少し大雑把で、実際にはFrankenPHPには大きく3つの側面があると感じました。
-
PHPを実行可能なWebサーバー
FrankenPHPは Caddy というGoで実装されたWebサーバー上でPHPを動かすのためのモジュールとして実行できる -
PHPを実行可能なCLI
FrankenPHPはCLI上からもPHPファイル指定して実行できる(この場合はWebサーバーでないのでCaddyは使わない) -
Goのパッケージ
FrankenPHPをGoのパッケージとして使えば、例えばGoのginやechoで実装されたWebサーバー上でPHPファイルを実行できたりする(通常はやらないと思うけど)
なぜこのような事ができるかというと、FrankenPHPにはPHPのソースが埋め込まれていて、それによりPHPがインストールされていなくてもFrankenPHPだけでPHPファイルを実行できるからです。そしてFrankenPHPはGoで実装されていることもあって、ビルドすれば1つの実行ファイルが出来上がり、その実行ファイルとPHPファイルさえあればPHPをできるという訳です。また一般的なPHP拡張機能も一通り入っているようです。
FrankenPHPをWebサーバーとして使う
WebサーバーでPHPを実行する場合、次のような組み合わせで使うことが多いと思います。
- Apache + PHPモジュール + PHPファイル
- Nginx + PHP-FPM + PHPファイル
FrankenPHPは前述のような特徴があるため、次のようなシンプルな組み合わせで実行可能です。
- FrankenPHP + PHPファイル
それでいてFrankenPHPの公式サイトによるとFPMより3.5倍速いという記載があったり、Caddyの公式ページにはSwooleやRoadRunnerより4倍速いとあります。
3.5x faster than FPM
With FrankenPHP, Caddy acts as a PHP application server that delivers PHP pages about 4x faster than Swoole or RoadRunner: no need for php-fpm (FastCGI).
Webサーバーとして起動する場合、例えば次のようなコマンドで実行します。サーバーの設定は
Caddyfile
や php.ini
を使ってカスタマイズできます。
./frankenphp php-server
ソースを軽く読んだ感じ、処理の流れとしてはこんな感じでPHPファイルを実行しているようです。
Caddy(Go)
--> FrankenPHPModule(Go)
--> FrankenPHP(Go&PHP)
--> cgo(php_execute_script)
--> Zend Engine
--> PHPファイルを実行
FrankenPHPをCLIツールとして使う
CLIからPHPファイルを実行する場合、次のようなコマンドで実行できます。
./frankenphp php-cli /path/to/your/script.php
FrankenPHPをGoのパッケージとして使う
このページに沿って環境を整えれば、こんな感じでGoの中からPHPファイルを実行することもできそうです。が、軽く試した感じうまくできませんでした。時間切れなので今回はここで諦めます。
package main
import (
"os"
"github.com/dunglas/frankenphp"
)
func main() {
const filePath = "test.php"
f, _ := os.Create(filePath)
defer f.Close()
f.Write([]byte("<?php\n echo 'Hello, FrankenPHP!';"))
os.Exit(frankenphp.ExecuteScriptCLI(filePath, []string{}))
}
既知の問題
このページにKnown Issuesがまとまっています。
上から適当にいくつかピックアップしますが、回避策などが提案されているのが良いですね。
- GoのWebフレームワークFiberでクラッシュする(解決に向けて動いているっぽい)
- PHP拡張機能 imap がサポートされていない(代替の拡張を推奨されている)
- XDebug がクラッシュすることがある(解決に向けて動いているっぽい)
- などなど
終わり
FrankenPHPについて軽くまとめてみました。かなり雑に調べたので間違っていることを書いているかもしれません。
以上です。
Discussion