PHPの「動的な闇」を払拭せよ:Hackの静的ディスパッチで堅牢なコードを手に入れる
やあ。HHVMの深淵から戻ってきた、Hackのアーキテクトだ。
PHPの自由度は魅力的だが、大規模開発においてその「動的な性質」は諸刃の剣だ。特に `$$var`(可変変数)や `$obj->$method()` といったコードは、HHVMの型チェッカー(Hack Typechecker)からすれば「何が代入されるか予測不能なブラックボックス」でしかない。
型チェッカーが推論を諦めた瞬間に、君たちのコードの安全性は崩壊する。今回は、レガシーなPHPの動的メタプログラミングを、Hackの厳格な静的ディスパッチに書き換える極意を授けよう。
—
1. なぜ「動的呼び出し」がHackの敵なのか
HHVMは、実行時にJITコンパイラが最高効率で機械語を生成するために、「型」を頼りにしている。`$obj->$method()` と書いた瞬間、HHVMは「どのクラスのどのメソッドが呼ばれるか」を事前に確定できず、最適化のチャンスをドブに捨てることになる。
何より、型チェッカーがその行の安全性を保証できなくなる。これが最大の問題だ。
—
2. 実践:`$$var` から Enum 駆動ディスパッチャへの転換
PHPでよく見る「文字列から変数にアクセスする」コードを、Hack流に書き換えよう。
レガシーPHP(避けるべきコード)
$action = ‘save’;
$$action(); // 実行時まで何が呼ばれるか不明。型チェック不可。
Hack流:EnumとFirst-class functionによる静的ディスパッチ
Enumを使って「許容される操作」を定義し、型を強制する。これがHackの作法だ。
namespace App;
enum Action: string {
Save = ‘save’;
Delete = ‘delete’;
}
class Processor {
public function save(): void { / 保存処理 / }
public function delete(): void { / 削除処理 / }
public function run(Action $action): void {
// 静的にメソッドを特定する。型チェッカーはこれを見て安心する。
switch ($action) {
case Action::Save:
$this->save();
break;
case Action::Delete:
$this->delete();
break;
}
}
}
ここがポイント:
- `Action` Enumを使うことで、`save` か `delete` 以外の値が混入する余地をコンパイル時に排除している。
- `switch` を使うことで、HHVMは「どのメソッドが呼ばれるか」を事前に100%追跡できる。
—
3. `$obj->$method()` を First-class function へ
メソッド名を文字列で動的に呼び出すのは、保守性の観点からも最悪の悪手だ。Hackでは、メソッドを「第一級関数」として扱うのが正解だ。
改善前:動的呼び出し
$method = ‘fetchData’;
$result = $obj->$method(); // 型チェッカーは $method の中身を知らない
改善後:`fun()` やクロージャの活用
特定のメソッドを呼び出したい場合は、そのメソッドを直接参照する。
class DataFetcher {
public function fetchData(): string { return “data”; }
}
function process(DataFetcher $obj): void {
// メソッドをFirst-class functionとして渡す
$handler = fun($obj->fetchData<>);
// 型チェッカーは $handler が何者かを知っている
$result = $handler();
}
—
4. 陥りやすい罠:型チェッカーとの戦い
初心者がよくやる間違いは、「動的である必要がないのに動的に書く」ことだ。
- エラー: `KeyedContainer` を無理やり動的に走査しようとする。
- 解決: 可能な限り `shape` 型(構造体)を使い、キーが確定している状態を作り出す。
// 良い例:shapeでキーを固定する
type User = shape(‘name’ => string, ‘id’ => int);
function processUser(User $u): void {
// $u[‘name’] は必ず文字列。動的なキーアクセスは不要。
echo $u[‘name’];
}
—
最後に:なぜそこまで厳格にするのか
Hackの静的型システムは、君たちを縛り付けるための檻じゃない。それは、「巨大なコードベースであっても、自信を持ってリファクタリングを可能にするための安全装置」だ。
`$$var` を使っている箇所を一つ見つけたら、それを Enum か `shape` に置き換えてみてほしい。型チェッカーが「合格」を出した瞬間、君のコードには確かな信頼が宿る。
ここをクリアすれば、もう君はHackの入り口に立っていると言っていい。さあ、次はもっと深いHHVMのメモリ管理の世界へ足を踏み入れようか。
質問があればいつでも歓迎する。コードを書く楽しさを、型と共に味わおう。