Mago: PHP開発が爆速になる?次世代の静的解析ツールを試してみた
はじめに
PHPでの開発において、コードの品質を高く保つことは、プロジェクトの成功に欠かせない重要な要素です。
これまで、コードフォーマッタ、リンター、静的解析といったツールは、それぞれ別のものを組み合わせて使うのが一般的でした。しかし、今回ご紹介する Mago は、これらの機能をたった一つに統合した、PHP界に現れたちょっと革新的なツールチェーンです。
私自身、普段のPHP開発では、次のようなツールを愛用していました。
- PHPStan: 頼れる静的解析ツール
- PHP-CS-Fixer: コードを美しく整えるフォーマッタ
これらのツールに大きな不満はなかったのですが、心のどこかで「静的解析、もう少し速くならないかな…」「ツールの設定がバラバラで、ちょっと面倒だな…」と感じていたのも事実です。
そこで今回は、最近注目を集めている Mago という、Rustで書かれた爆速PHPツールチェーンを実際に試してみることにしました。
せっかくなので、PHPがどうやってRust製のパワフルなバイナリを使っているのか、その裏側も少し覗いてみたいと思います。
今回テストで作成したリポジトリはこちらになります。
Magoとは
Magoは、人気のプログラミング言語 Rust で実装された、PHPのための開発ツールです。
「とにかく速く!」をコンセプトにゼロから設計されており、他のどのツールよりも高速にコードの解析やフォーマットを実行します。
強力な静的アナライザー、自動修正も可能なリンター、そして独自の哲学を持つコードフォーマッター。これら全てが、たった一つのバイナリにギュッと詰まっています。
ざっくり言うと、PHPStan, PHP-CS-Fixer, Psalm といったツール界の”三種の神器”を一つにまとめたようなイメージです。
これは期待が高まりますね!
Setup
さっそくComposerでインストールして、初期設定をしてみましょう。
Composer経由でインストール
おなじみのコマンドを一発実行するだけです。
composer require --dev carthage-software/mago
これだけで、あなたの環境に最適化されたRust製の高速なバイナリがダウンロードされ、./vendor/bin/mago
から使えるようになります。シンプルで良いですね。
初期化
インストールが終わったら、mago init
コマンドで設定ファイル mago.toml
を作ります。
まるで賢いアシスタントに質問されているかのように、対話形式でサクサク設定が進んでいきます。
./vendor/bin/mago init
Mago
⬩ Welcome! Let's get you set up.
╭─ Step 1: Project Setup
│
│ Found `composer.json`. Use it to auto-configure project paths & PHP version? · yes
│
│ Reading composer.json...
│ Project settings detected!
╰─
╭─ Step 2: Linter Configuration
│
│ The Linter checks your code for stylistic issues and inconsistencies.
│ Use `composer.json` to auto-detect framework integrations? · yes
│
│ Detecting integrations from composer.json...
│ Done!
╰─
...あとは流れに沿ってYes/Noと答えるだけ!...
✅ Configuration file created successfully!
╭─ 🎉 You're all set!
│
│ Mago is now configured for your project.
│
│ What's next?
│ - Run `mago lint` to check for issues.
│ - Run `mago analyze` to find type errors.
│ - See formatting changes with `mago fmt --dry-run`.
│
│ Tip: Use the `--help` flag on any command for more options.
│
╰─ For full documentation, visit: https://mago.carthage.software/
はい、完了です!
フォーマッタやリンターの細かいルールは、生成された mago.toml
でいつでも調整できます。
使ってみる
それでは、Magoの主な機能を使ってみましょう。
1. Formatter(フォーマッター)
独自の哲学を持つコードフォーマッター。PSR-12規約にバシッと準拠させてくれるので、もうレビューでインデントの指摘に時間を取られることはありません。
# プロジェクト内のファイルを一括で美しく整形
./vendor/bin/mago fmt
# 「修正はしないで、どこが変わるかだけ教えて」という場合に
./vendor/bin/mago fmt --check
# 変更内容をプレビュー表示
./vendor/bin/mago fmt --dry-run
--dry-run
を実行すると、差分が分かりやすく表示されます。便利!
diff of 'src/Synthesizer/Value/Cutoff.php':
--- original
+++ modified
@@ -12,36 +12,36 @@
*/
final readonly class Cutoff
{
- /** 最小カットオフ周波数(Hz) */
- public const float MIN = 20.0;
+ /** 最小カットオフ周波数(Hz) */
+ public const float MIN = 20.0;
...
2. Linter(リンター)
コードのスタイルに関する問題や、「なんだかこのコード、イケてない匂いがする…」といった"コードの匂い"を超高速で見つけてくれます。「神は細部に宿る」と言いますが、その細部をMagoがしっかりチェックしてくれます。
# プロジェクト全体をリント実行
./vendor/bin/mago lint
# 「未使用の変数」だけ、ピンポイントでチェックしたい時に
./vendor/bin/mago lint --only unused-variable
問題が見つかると、どこがどう問題で、どうすれば良いか親切に教えてくれます。
warning[constant-type]: Class constant `MIN` is missing a type hint.
┌─ src/Synthesizer/Value/Cutoff.php:16:2
│
16 │ public const MIN = 20.0;
│ ^^^^^^^^^^^^^^^^^^^^^^^^ Class constant `MIN` is defined here
│
= Adding a type hint to constants improves code readability and helps prevent type errors.
= Help: Consider specifying a type hint for `MIN`.
3. Analyzer(静的解析)
Magoの真骨頂とも言える、強力な静的解析エンジンです。コードを実行する前に、論理的なエラーや型の不一致といった潜在的なバグを発見します。実行時エラーで頭を抱える前に、Magoがそっと教えてくれる安心感は絶大です。
# 静的解析を実行して、バグの芽を摘む
./vendor/bin/mago analyze
エラーが見つかると、これもまた非常に分かりやすく指摘してくれます。
error[non-existent-class]: Class `Takemo101\MagoExample\Synthesizer\Value\InvalidArgumentException` not found.
┌─ src/Synthesizer/Value/Cutoff.php:27:23
│
27 │ throw new InvalidArgumentException(sprintf(
│ ^^^^^^^^^^^^^^^^^^^^^^^^ `Takemo101\MagoExample\Synthesizer\Value\InvalidArgumentException` is not defined or cannot be autoloaded
│
= Help: Ensure the name is correct, including its namespace, and that it's properly defined and autoloadable.
4. Lexer & Parser (上級者向け)
PHPコードを「抽象構文木(AST)」という構造的なデータに変換する機能です。
普段はあまり使いませんが、ツールの内部動作に興味がある方には面白いかもしれません。
# コードの構造を覗いてみる
./vendor/bin/mago ast src/Synthesizer/Oscillator.php
Github Actionsに組み込む
もちろん、CI/CDのパイプラインにも簡単に組み込めます。
これで、プルリクエストごとにコード品質が自動でチェックされ、チーム全体の品質維持に貢献します。
PHPは、どうやってRustの力を借りている?
Magoの圧倒的なパフォーマンスは、Rustで書かれたネイティブバイナリのおかげです。
では、PHPからどうやってこの強力な助っ人を呼び出しているのでしょうか?
結論から言うと、PHPに標準で備わっている proc_open
という関数を使っています。
Magoのスクリプトは、このproc_open
を使ってバイナリを起動し、コマンドの引数を渡し、結果を受け取っています。
まとめ
Magoは、PHP開発における静的解析の体験を大きく変える可能性を秘めた、まさに革命的なプロジェクトです。
圧倒的なパフォーマンス
従来のツールと比べて 10倍から100倍近い速度向上 は伊達じゃありません。数分かかっていたCIのジョブが数秒で終わる世界...想像しただけでワクワクしますね。
Magoに乗り換える"おいしい"理由
-
設定のシンプルさ: あちこちに散らばっていた設定ファイルが、
mago.toml
一つにまとまります。 - 体験の一貫性: フォーマッタ、リンター、アナライザーが三位一体となり、一貫したルールでコードをチェックできます。
- モダンな標準: PSR-12準拠はもちろん、最新のベストプラクティスが取り入れられています。
ベータ版としての現状と未来
現在はまだベータ版ですが、開発は非常に活発です。この技術的な優位性を考えると、近い将来、PHP開発における標準ツールの一つとなる可能性は非常に高いでしょう。
「速度は機能である」 —— Magoはこの哲学を体現しています。単なるツールの置き換えではなく、PHP開発の体験そのものを向上させてくれる存在です。
このスピードと快適さは、一度試してみる価値大アリです!
Discussion