こんにちは!日々のPHP開発、お疲れ様です。
皆さんは、プロジェクトごとのテスト実行や、コーディング規約のチェック(静的解析)、そしてデプロイ前のビルド作業などにおいて、このような面倒臭さに直面したことはありませんか?
- 「あのプロジェクトのテストコマンド、引数に何を渡すんだっけ……?」
- 「プロジェクトAではPHPUnitを直接叩き、プロジェクトBでは`vendor/bin/phpunit`を叩く必要がある……統一感がないな」
- 「複数のツール(PHPCS、PHPStan、PHPUnit)を順番に手動で実行するのが地味にストレスだ」
開発を進めるにつれて、プロジェクト固有の「お作法」やコマンドが増え、脳のメモリを無駄に消費してしまいますよね。
実は、PHPのパッケージ管理ツールとしておなじみの Composer を使うと、ライブラリを入れるだけでなく、プロジェクト専用の高機能な「タスクランナー」 に変身させることができるんです。npmにおける `package.json` の `scripts` と同じような仕組みですね。
これをマスターすれば、チームメンバー全員が `composer test` や `composer check` と打つだけで、同じ高品質なワークフローを再現できるようになります。毎日のコーディングが劇的に楽になりますよ。
今回は、Composerの `scripts` 機能をフル活用して、開発ワークフローを美しく自動化する裏技を、基礎から丁寧にお伝えしていきますね!
—
1. なぜComposerの「scripts」を使うべきなのか?
そもそも、「なんでわざわざComposer経由でコマンドを実行するの? ターミナルに直接書けばいいじゃん」と思いますよね。ここには、開発効率と保守性を爆発的に高めるアーキテクト的な理由が3つあります。
1. 環境依存の絶滅(パス問題の解決)
`vendor/bin/phpunit` のように、ベンダーディレクトリ以下の実行ファイルパスは環境によって微妙に変わることがあります。Composerは、実行時にプロジェクトローカルな `vendor/bin` に自動でパスを通してくれるため、あなたはパスの深さを気にする必要がなくなります。
2. コマンドの抽象化と統一(認知負荷の軽減)
裏側で複雑なオプション(例: `vendor/bin/phpstan analyse src –level=max`)を指定していても、表側は `composer analyze` というシンプルなコマンドに隠蔽できます。新しいメンバーが来ても、READMEに「`composer check` を実行してください」と書くだけで済みます。
3. 一連の処理の連鎖(パイプライン化)
「コードフォーマットの修正 -> 静的解析 -> 単体テスト」という一連の流れを、1つのコマンドで順番に実行させることができます。
それでは、実際にその仕組みを見ていきましょう!
—
2. 基礎セットアップ:最小構成のプロジェクトを作ろう
百聞は一見にしかず。手を動かしながら理解するために、実験用の小さなPHPプロジェクトを作ってみましょう。
ターミナルを開き、任意の場所にディレクトリを作成して移動します。
作業用ディレクトリを作成して移動
mkdir composer-script-demo
cd composer-script-demo
最低限のcomposer.jsonを対話なしで生成
composer init –no-interaction \
–name=”demo/script-project” \
–description=”Composer scripts demonstration project” \
–author=”Your Name
–type=”project” \
–license=”MIT”
生成された `composer.json` を覗いてみてください。まだ何も依存関係が入っていない素の状態です。
ここに、開発を強力にサポートしてくれる定番ツール、PHPUnit(テストフレームワーク) と PHP CodeSniffer(コーディング規約チェッカー) を開発用依存関係(`–dev`)としてインストールします。
PHPUnitとPHP CodeSnifferを開発用としてインストール
composer require –dev phpunit/phpunit squizlabs/php_codesniffer
これで、プロジェクトのローカル環境にこれらを実行する準備が整いました。通常であれば、これらを実行するには `vendor/bin/phpunit` や `vendor/bin/phpcs` と叩く必要があります。
—
3. 「scripts」セクションの魔術:composer.jsonをカスタマイズする
いよいよ本題です。`composer.json` に `scripts` セクションを追加し、面倒なコマンドをスマートに呼び出せるように定義していきましょう。
プロジェクトのルートにある `composer.json` をエディタで開き、以下のように `scripts` キーを追加してください。
{
“name”: “demo/script-project”,
“description”: “Composer scripts demonstration project”,
“type”: “project”,
“license”: “MIT”,
“require”: {
“php”: “>=8.1”
},
“require-dev”: {
“phpunit/phpunit”: “^10.0”,
“squizlabs/php_codesniffer”: “^3.7”
},
“scripts”: {
/
- 1. テストを実行するショートカット
- 「composer test」と打つだけで、vendor/bin/phpunit が走ります。
/
“test”: “vendor/bin/phpunit”,
/
- 2. コーディング規約をチェックするショートカット
- PSR-12規約に沿っているかを src ディレクトリに対して検証します。
/
“cs:check”: “vendor/bin/phpcs –standard=PSR12 src/”,
/
- 3. コーディング規約違反を自動修正するショートカット
- 自動修正可能なものは phpcbf で一発クリアにします。
/
“cs:fix”: “vendor/bin/phpcbf –standard=PSR12 src/”,
/
- 4. 複数のタスクを順番に実行する「複合タスク」
- 配列で記述すると、上から順番に実行され、途中でエラー(終了コード非0)が出るとそこで止まります。
/
“check”: [
“@cs:check”,
“@test”
]
}
}
ここがエンジニアのこだわりポイント!
注目してほしいのは、最後の `”check”` の定義です。配列の中に `@cs:check` や `@test` とアットマーク(`@`)付きで他のスクリプトを指定していますよね。
これはComposerの機能で、「定義済みの別のスクリプトを呼び出す」 という意味になります。これにより、コードの重複を避けながら、美しくタスクをチェーンさせることができます。
—
4. 精度高い「HelloWorld」的動作確認
設定が完了したら、実際にこのタスクランナーがどのように動くのかを体験してみましょう。
動作確認のために、簡単なソースコードとテストコードを配置します。
① テスト対象のクラスを作成
`src/Calculator.php` を作成し、簡単な足し算クラスを書きます。あえて少しPSR-12に違反する書き方(インデントの乱れなど)をしてみましょう。
② テストコードを作成
`tests/CalculatorTest.php` を作成します。
assertEquals(4, $calc->add(2, 2));
}
}
(※PHPUnit 10系に合わせて名前空間や設定を適宜調整してください)
—
いざ、Composerスクリプトを実行!
それでは、ターミナルから私たちが定義した魔法のコマンドを叩いてみましょう。
1. コーディング規約チェック (`composer cs:check`)
まずは規約違反があるかどうかをチェックします。
composer cs:check
【実行ログのイメージ】
> vendor/bin/phpcs –standard=PSR12 src/
FILE: /path/to/project/src/Calculator.php
———————————————————————-
FOUND 1 ERROR(S) AFFECTING 1 LINE(S)
———————————————————————-
7 | ERROR | [x] Opening brace should be on the same line for the class declaration
———————————————————————-
PHPCBF CAN FIX THE 1 MARKED VIOLATION AUTOMATICALLY
———————————————————————-
見事に、PSR-12規約違反(クラスの開き括弧の位置)を検知してくれました!
2. 自動修正 (`composer cs:fix`)
「直すのめんどくさいな……」と思ったら、あのコマンドの出番です。
composer cs:fix
実行すると、ツールが自動でコードを整形し、エラーを消し去ってくれます。
3. テストの実行 (`composer test`)
次に、単体テストを走らせます。
composer test
【実行ログのイメージ】
> vendor/bin/phpunit
PHP Unit 10.x.x by Sebastian Bergmann and contributors.
Runtime: PHP 8.1.x
Configuration: …
. 1 / 1 (100%)
Time: 00.00 ds, Memory: 6.00 MB
OK (1 test, 1 assertions)
美しい!一発でテストが緑色(成功)になりました。
4. 総仕上げのワークフロー実行 (`composer check`)
そして、これらすべてを統合した究極のコマンドを叩きます。
composer check
このコマンドを叩くだけで、裏側で `cs:check`(規約チェック)が走り、それが成功したら自動的に `test`(単体テスト)が実行されます。もし途中で規約違反やテスト失敗があれば、そこで即座に処理がストップし、CI/CDパイプラインの前段階としての「ローカル品質ゲート」が完璧に機能します。
—
5. さらに現場で役立つ!知っておくべき応用テクニック
最後に、シニアエンジニアとして現場でよく使う「一歩進んだテクニック」をいくつかご紹介しておきますね。
① スクリプトに引数を渡す方法
例えば、特定のテストファイルだけを `composer test` 経由で実行したい場合はどうすればいいでしょうか?
実は、Composerスクリプトの末尾に `–`(ダブルハイフン)を挟んで引数を渡すと、内部のコマンドに引数がそのまま転送されます。
“scripts”: {
“test”: “vendor/bin/phpunit”
}
この定義に対し、以下のように実行します。
— 以降の引数が vendor/bin/phpunit にそのまま渡る
composer test — tests/CalculatorTest.php
これで、柔軟性を損なわずにコマンドを共通化できます。
② コマンド実行の前後でフックを仕掛ける(Event Scripts)
Composerには、特定の操作(`install` や `update` など)の前後(`pre` / `post`)に自動でスクリプトを走らせるイベントフック機能があります。
例えば、「依存関係が更新されたら、自動でキャッシュをクリアする」という処理は以下のように書けます。
“scripts”: {
“post-update-cmd”: [
“Illuminate\\Foundation\\ComposerScripts::postUpdate”,
“@php artisan cache:clear”
]
}
チームメンバーが `composer update` を叩いた後、「あ、キャッシュクリアし忘れた!」という事故を完全に防ぐことができます。
—
まとめ
今回は、Composerの `scripts` 機能を使って、プロジェクト固有のタスクランナーを構築する方法を解説しました。
- 面倒なベンダーパスの指定を隠蔽し、短いコマンドに統一できる
- `check` のように複数のタスクをチェーンさせて、品質チェックを自動化できる
- チーム全体の開発体験(DX)が向上し、環境差異や手順ミスによる無駄なストレスが消え去る
今日からあなたのプロジェクトでも、`composer.json` に `scripts` を定義して、開発ワークフローをスマートに自動化してみてください。毎日のコーディングが驚くほど快適になりますよ!
それでは、良きPHPライフを!