-- Views
December 22, 24
スライド概要
PHP Conference Japan 2024の登壇資料です
Rustで作るPHP拡張モジュール: PSR-7ライブラリ編 PHP Conference Japan 2024 荒巻拓哉 (@takaram71)
自己紹介 ● ● ● ● 荒巻 拓哉 X: @takaram71 PHPer 6年目 株式会社ラクス
おわび
おわび ● ライブラリが完成しませんでした🙇 ○ 一部は出来ているので、作る中での学び・感想はお話しします ○ https://github.com/takaram/psr7-rs ● 「明日から役に立つ」的なセッションではないです ○ 仕事で拡張モジュール作らない(ですよね?) ○ PHPインタプリタの実装に少し詳しくなれるかも
アジェンダ ● 前提知識 ○ Rust ○ PHP拡張モジュール ○ PSR-7 ● RustでPHP拡張モジュール作成 ● PHPerから見たRust
Rustってどんな言語?
Rust ● コンパイル言語 ○ 事前に実行用のバイナリファイルを作る ● 特徴 ○ パフォーマンスに優れている ○ メモリ安全性が高い ○ 所有権システム
所有権 / ライフタイム ● データを参照・書き換えできるタイミングのルール ● データがいつ参照できなくなるか、コンパイラが解析可能 ○ その時点でメモリ解放 ○ C言語だとプログラマが管理 → 不具合起きやすい ● PHPなど多くの言語にある「ガベージコレクション (GC)」が不要 ○ パフォーマンス
PHP拡張モジュール
PHP拡張モジュール ● PHPの構成要素 ○ Zend Engine: PHPコードの解釈、実行 ○ 拡張モジュール:関数・クラスの定義など ● 標準関数・クラスも拡張モジュール ○ json_encode():json拡張モジュール ○ DateTimeクラス:date拡張モジュール
PHP拡張モジュール ● (たいてい)C言語で実装 ○ Zend EngineのAPIを利用 ■ ■ 関数、構造体 Zend EngineもC言語で実装されている
PSR-7
PSR-7 ● HTTPリクエスト・レスポンスをオブジェクト指向で扱うためのインター フェース ● $_POST, $_FILES などの代わり
PSR-7のインターフェース ● Psr\Http\Message ○ ○ ○ ○ ○ ○ ○ MessageInterface RequestInterface ResponseInterface ServerRequestInterface StreamInterface UploadedFileInterface UriInterface
Rustで作るPHP拡張モジュール
ext-php-rs https://github.com/davidcole1340/ext-php-rs Zend APIをRustから呼び出すためのライブラリ
Hello world 公式マニュアルにしたがってHello worldしてみる https://davidcole1340.github.io/ext-php-rs/getting-started/hello_w orld.html
Hello world
Hello world
Hello world
PHPの型 ⇔ Rustの型 PHP Rust string &str, String, Binary*, BinarySlice* int i8, u8, i16, u16, i32, u32, i64, u64, isize, usize float f32, f64 array Vec, HashMap object ZendObject *: ext-php-rs独自の型
Rustで作るPSR-7
クラス作成 ● #[php_class] でPHPにHelloクラスが 生える ○ #[php_class(name="Foo\\Hello")] で名前指定 ● #[php_impl] でメソッド実装 ● コンストラクタとsayHello() メソッド ○ キャメルケースに変換される
クラス作成 ● クラス継承、インターフェース実装も可能 ○ #[extends(ce::exception())] ○ #[implements(ce::arrayaccess())] ● PSR-7 のインターフェースはPHPのユーザーランド実装 ○ 拡張モジュール読み込み時点では存在しない
これはできない Rust PHP
こうする Rust PHP
特殊な型:nullable ● RustのOption<T>型を利用 ○ Some(value) ○ None ● Option<i64> が int|null に対応
特殊な型:mixed ● Zval型を利用 ○ Zend Engineが用意している構造体 ○ PHPの「どんな型も入れられる変数」の正体 ○ RustでZvalをそのまま受け取ることもできる
特殊な型:resource ● Rust標準には対応する型はない ● C言語のzend_resource構造体の薄いラッパーがあるだけ ● 今回は扱うことを避けた
特殊な型:void ● 空タプル () を返す ● タプル:配列に似た型 ○ Python, Kotlin などにも同じようなものあり
例外 ● Result型を利用 ● Rustには例外がない ○ Result<T, E>型 ■ ■ Ok(value) Err(err) ● PhpResult<T>: Result<T, PhpException> の型エイリアス ○ PhpException: エラーメッセージ、コード、例外クラス
いちPHPerから見たRust
堅牢 ● 列挙型 ○ Option, Result ○ nullチェック漏れ、エラーハンドリング漏れがない
コンパイラが厳しくて優しい ● 所有権が難しい ○ ひたすらコンパイルエラー ● エラーメッセージで「ここをこう直すといい」と教えてくれる
開発環境・ツールが充実 ● 公式ツール ○ clippy: Lintツール ○ rustfmt: フォーマッター ● IDE ○ RustRover ■ ■ JetBrains製 非商用利用は無料
まとめ
まとめ ● RustでPHP拡張モジュールを作れる ● Rustという言語 ○ PHPとは考え方が異なる部分も多い言語 ○ 特に所有権ははじめは戸惑う ● PHPの内部構造を学べる