【入門編】レガシーPHPの可変変数($$var)と動的メソッド呼び出しの根絶:静的ディスパッチへの移行 – Hack言語 コア・静的型システムとHHVMのアーキテクチャ解析バイブル

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のメモリ管理の世界へ足を踏み入れようか。

質問があればいつでも歓迎する。コードを書く楽しさを、型と共に味わおう。

タイトルとURLをコピーしました