こんにちは!開発現場で日々コードと向き合っていると、ふと「あれ、なんでパッケージのインストールにこんなに時間がかかるんだろう?」とか、「ライブラリのソースコードをちょっと書き換えてデバッグしたいのに、VENDORフォルダの中身だから直接いじれない…」なんてモヤモヤを感じたことはありませんか?
今回は、PHPのパッケージ管理における心臓部、Composerの依存関係解決エンジンを深くハックしていきましょう。
特に、現場で意外と見落とされがちな `–prefer-source` と `–prefer-dist` という2つのオプションを取り上げます。「なんとなくデフォルトのまま使っている」という方にこそ、この違いを完全に理解してほしいのです。これをマスターすれば、CI/CDパイプラインの爆速化や、複雑なバグ調査時のストレスフリーなデバッグ運用が手に入り、毎日のコーディングが劇的に楽になりますよ。
それでは、初心者の方にもすんなり本質が伝わるよう、基礎の基礎からアーキテクト視点の裏技まで、優しく紐解いていきましょう。
—
1. Composerとは何か?(その役割と基礎のキソ)
PHPで開発をする際、世の中の優秀なライブラリ(例えば、ルーティング機能やデータベース接続機能など)をゼロから全て自分で書く人はいませんよね。それらを安全かつ効率的に集めて管理してくれるのが Composer です。
Composerの役割は、いわば「あなたのプロジェクトの優秀な物流管理マネージャー」です。
「このライブラリのバージョン2.0が必要で、それが動くためには別のあのライブラリも必要で…」という複雑なパズル(依存関係)を自動的に計算し、整えてくれます。
最速のインストールと基礎セットアップ
まずは、あなたの手元でComposerが動く状態を確認しましょう。すでに導入済みの方も、最新の状態にアップデートするつもりで見てみてください。
ターミナルを開き、以下のコマンドを順に実行します。
公式サイトから安全にComposerのインストーラーを取得し、phpで実行してローカルに配置します
php -r “copy(‘https://getcomposer.org/installer’, ‘composer-setup.php’);”
インストーラーが改ざんされていないかハッシュ値(SHA-384)を検証します
php -r “if (hash_file(‘sha384’, ‘composer-setup.php’) === ‘e21205b207c3ff031906575712edab6f13eb0b361f2085f1f1237b7126d785e826a450292b1cfd1d6c8a325568c7c41f’) { echo ‘Installer verified’; } else { echo ‘Installer corrupt’; unlink(‘composer-setup.php’); } echo PHP_EOL;”
composer.phar(実行ファイル)をシステム全体で使えるように移動します
sudo php composer-setup.php –install-dir=/usr/local/bin –filename=composer
不要になったインストーラーファイルを削除します
php -r “unlink(‘composer-setup.php’);”
正しくインストールできたか、バージョンを確認してみましょう。
composer –version
期待される出力例: Composer version 2.x.x …
これで準備は完了です!
—
2. 精度高い「Hello World」的動作確認:最小限のプロジェクトを作ろう
Composerの動きを目で見える形で理解するために、超シンプルなプロジェクトを立ち上げてみます。
任意のディレクトリに移動し、作業用フォルダを作成してください。
mkdir composer-lab
cd composer-lab
ここに、Composerの心臓部である設計図 `composer.json` を作成します。今回は、PHPの便利なユーティリティ関数が集まった `symfony/string` という軽量なパッケージを導入してみましょう。
{
“name”: “developer/lab”,
“description”: “Composer prefer-source and prefer-dist laboratory”,
“require”: {
“symfony/string”: “^6.4”
}
}
- `require`: このプロジェクトが動くために絶対にないと困る外部ライブラリ(本番用)を定義するブロックです。
では、この設計図をもとに、いよいよパッケージをインストールしてみます。ここで今回のメインテーマである `–prefer-dist` が登場します。
composer install –prefer-dist
実行結果のログ(イメージ):
Installing dependencies from lock file
Verifying lock file contents can be installed on current platform
Package operations: 2 installs, 0 updates, 0 removals
- Downloading symfony/polyfill-ctype (v1.31.0)
- Downloading symfony/string (v6.4.12)
Generating autoload files
おめでとうございます!これで `vendor/` ディレクトリが生成され、ライブラリが使えるようになりました。
では、実際に動くか確認するPHPファイル(`index.php`)を書いてみましょう。
slug();
echo “変換前: Hello, Composer Hackers! Let us dive deep.\n”;
echo “変換後: ” . $slug . “\n”;
実行してみます。
php index.php
出力結果:
変換前: Hello, Composer Hackers! Let us dive deep.
変換後: hello-composer-hackers-let-us-dive-deep
見事にライブラリが機能し、文字列が変換されました!これがComposerを使った開発の基本形です。
—
3. エンジニアの核心:「–prefer-source」と「–prefer-dist」の内部挙動と違い
さて、ここからが本題、アーキテクトとしての真骨頂です。
先ほど何気なく使った `–prefer-dist` と、もう一つのオプションである `–prefer-source` は、内部で一体何をしているのでしょうか?
–prefer-dist (ディストリビューション優先:デフォルト)
- 内部挙動: GitHub等のリポジトリから、余計なテストコードやGit履歴を削ぎ落とした軽量な「ZIPアーカイブ」をダウンロードし、解凍して配置します。
- メリット: ダウンロードが圧倒的に速く、ファイルサイズも小さいため、ネットワーク帯域を圧迫しません。
- デメリット: 単なる「ファイルの束」としてダウンロードされるため、`vendor/` の中にあるライブラリのコードを書き換えても、Gitの管理下に置くことができません(パッチを当ててコミットするといった芸当が不可能)。
–prefer-source (ソースコード優先)
- 内部挙動: パッケージの元となるGitリポジトリを直接クローン(`git clone`)し、内部でGitのサブモジュールや特定コミットの状態にチェックアウトします。さらに、`.git` ディレクトリがそのまま残ります。
- メリット: ライブラリのソースコード内部に直接Gitの履歴が存在するため、その場でバグを見つけて修正し、自分のブランチとしてパッチ(Git差分)を切ったり、元のリポジトリにPull Requestを送るような開発がその場で可能になります。
- デメリット: Gitの履歴やメタデータごと取得するため、ダウンロードに時間がかかり、ディスク容量も消費します。
—
4. 現場でどう使い分ける?:環境別・極意のアーキテクチャ
この2つの違いを理解したあなたなら、環境ごとにどちらを選ぶべきか、もうお気づきでしょう。現場で震えるほど役立つ使い分けの基準を伝授します。
① CI/CD環境・本番サーバー(Production / CI)
選ぶべきオプション: `–prefer-dist` (またはオプションなしのデフォルト)
- 理由: CI(GitHub ActionsやGitLab CIなど)や本番サーバーでは、ライブラリのソースコードを「改造」することは絶対にありません。必要なのは「一刻も早く、正確なバージョンのコードを配置してビルドを完了させること」です。
- 知見: さらにCI環境では、`composer install` の実行時間を短縮するため、`vendor/` ディレクトリ自体をキャッシュする仕組みを組み合わせます。
GitHub Actionsでの爆速キャッシュ&インストール設定の例
- name: Cache Composer dependencies
uses: actions/cache@v3
with:
path: vendor
key: ${{ runner.os }}-composer-${{ hashFiles(‘/composer.lock’) }}
restore-keys: |
${- runner.os }}-composer-
- name: Install Dependencies
run: composer install –prefer-dist –no-progress –no-interaction
`–no-progress` や `–no-interaction` を組み合わせることで、余計な画面描画を省き、CIの実行時間を数秒単位で削り取ることができます。
② ローカル開発環境 & ライブラリのバグ調査・パッチ当て(Local / Debugging)
選ぶべきオプション: `–prefer-source`
- 理由: 「あれ、使っている外部ライブラリのこのメソッド、なんか挙動おかしくないか?」という場面に遭遇したことはありませんか?通常、`vendor/symfony/string` の中身を書き換えても、次に `composer update` を走らせた瞬間にすべて上書きされて消滅します。
- 知見: しかし、あらかじめ `–prefer-source` でインストールしておけば、`vendor/symfony/string` は独立したGitリポジトリとして存在します。そのため、そのディレクトリに移動して自由に実験用コードを差し込んだり、ローカルでパッチを当てて検証することが劇的に簡単になります。
例:ローカルで特定のライブラリをソースコード(Gitクローン)として強制インストールする
composer require symfony/string –prefer-source
実際に `vendor/symfony/string` ディレクトリに入って `git status` を叩いてみてください。なんと、ちゃんとGitのワーキングツリーとして認識される感動を味わえます。
—
5. まとめ:今日からあなたの開発が変わる
今回は、Composerの依存関係解決エンジンにおける `–prefer-source` と `–prefer-dist` の決定的な違いと、それを環境ごとに最適に使い分けるアーキテクチャの極意をお伝えしました。
- 本番やCIは、スピードと軽量さを重視して `–prefer-dist`
- ローカルでの深いデバッグや、OSSのライブラリにパッチを当てて検証したいときは `–prefer-source`
この選択の意図をチーム全体で共有できるようになると、ビルドの待ち時間が減るだけでなく、「ライブラリのバグに直面しても恐れない、自立したエンジニアリング組織」へと一歩近づくことができます。
これをマスターしたあなたなら、明日からのパッケージ管理がもっと楽しく、ロジカルになるはずです。快適なComposerライフをエンジョイしてください!