こんにちは!開発現場で日々、コードとインフラに向き合っている先輩エンジニアです。
PHPのプロジェクトを進めていると、避けて通れないのがパッケージ管理ツール「Composer」ですね。フレームワークやライブラリをサクッと導入できて本当に便利なのですが、開発を続けていくうちに、こんな恐怖のメッセージに遭遇したことはありませんか?
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 40960 bytes) in phar:///usr/local/bin/composer/src/Composer/DependencyResolver/Horde/Crates/Hub/依存関係の迷宮…
画面いっぱいに赤字で現れる 「Memory Exhausted(メモリ枯渇)エラー」 です。「えっ、私のパソコンのスペックが低いの?」「さっきまで動いていたのに、なぜ急に!?」と、冷や汗をかいてしまいますよね。
でも、安心してください。このエラーは、あなたのパソコンの性能不足ではなく、Composerの「内部の仕組み」とPHPの「初期設定」のミスマッチが原因で起きる必然の現象なのです。
今回は、この厄介なメモリ不足エラーの根本原因をスッキリ解き明かし、二度と怯えなくてよくなる「完全な解決策」を、優しく論理的に解説していきます。これをマスターすれば、毎日のライブラリ管理が驚くほどスムーズになりますよ!
—
そもそもComposerとは? なぜメモリを大量消費するのか
まずは、Composerというツールの役割と、なぜメモリを食い潰すのかという「内部の裏側」を少しだけ覗いてみましょう。
Composerは、PHPのプロジェクトで使う外部ライブラリ(例えば、Laravelの各パッケージや、認証ライブラリなど)を一元管理してくれるマネージャーです。
私たちが `composer.json` という設計図に「このライブラリが欲しい」と書くと、Composerは世界中からそのライブラリを集めてきます。
ここで重要なのが、「依存関係(Dependency)の解決」という処理です。
ライブラリAを動かすにはライブラリBのバージョン1.2以上が必要で、さらにライブラリBはライブラリCを……という複雑な網の目を、Composerは一瞬で計算し尽くします。この計算、実は数学的なグラフ理論に基づくものであり、数千・数万に及ぶパッケージの組み合わせをメモリ上で総当たりに近い形でシミュレートしています。
そのため、プロジェクトが大きくなると、PHPがデフォルトで用意している「128MB」といった小さなメモリ領域では一瞬でオーバーフローしてしまうのです。これが、Memory Exhaustedの正体です。
—
基本のセットアップと動作確認:まずはここから
本題の解決策に入る前に、Composerの基本と、正しく動いているかを確認する「HelloWorld」的なステップをおさらいしておきましょう。
1. インストールと動作確認
Composerは公式ドキュメントに従ってグローバルにインストールするのが一般的です。ターミナル(CLI)を開き、正しくインストールされているか確認してみましょう。
Composerのバージョンを確認する(正しくインストールされていればバージョン情報が出ます)
composer –version
2. 小さなプロジェクトでの動作確認(HelloWorld)
適当な空ディレクトリを作り、Composerの挙動を確かめてみます。
テスト用ディレクトリを作成して移動
mkdir composer-test && cd composer-test
試しに人気のユーティリティライブラリ(Carbonなど)をインストールしてみる
composer require nesbot/carbon
実行すると、内部で依存関係が解決され、`vendor`フォルダと `composer.json` / `composer.lock` が生成されます。
これがComposerの基本の動きです。この「依存関係の解決」こそが、メモリを大量に消費する犯人なわけです。
—
現場で即効性抜群!「Memory Exhausted」を完全にねじ伏せる3つの解決策
それでは本題です。`composer update` や `composer install` でメモリ不足が発生した際、私たちが取るべきアプローチは主に3つあります。上から順に試していけば、確実にエラーを回避できます。
—
解決策1:PHPのメモリ制限(memory_limit)を一時的・恒久的に解除する
PHPはデフォルトの状態だと、1つのスクリプトが使えるメモリに上限(大抵は `128M`)が設けられています。Composerには少し厳しすぎる制限です。これをコマンド実行時に直接広げてあげましょう。
A. コマンド実行時に一時的に制限を解除する(最も手軽)
一番手っ取り早いのは、コマンドの引数に `-d memory_limit=-1` を渡す方法です。`-1` を指定すると、メモリ制限が無限(無制限)になります。
メモリ制限を無制限にして、安全にアップデートを実行する
php -d memory_limit=-1 /usr/local/bin/composer update
※ `/usr/local/bin/composer` の部分は、お使いの環境のComposerへのパスに読み替えてください(単に `composer update` の前に `php -d memory_limit=-1` をつけるだけでも動く環境が多いです)。
B. php.iniを書き換えて恒久的に解決する(根本治療)
毎回 `-d memory_limit=-1` を打つのは面倒ですよね。使っているPHPの環境設定ファイル `php.ini` を直接書き換えて、デフォルトのメモリを増やしてしまいましょう。
; php.ini の中での設定例
; 128MBから、十分な余裕を持たせて2GB(2048M)に変更します
memory_limit = 2048M
> 先輩からのアドバイス:
> 開発用マシンのローカル環境であれば、思い切って `memory_limit = -1` に設定してしまっても実害はほぼありません。サーバーのメモリを食い潰す心配がある本番環境では避けるべきですが、開発端末なら心置きなく解放して大丈夫です。
—
解決策2:`–no-dev` オプションで不要な負荷を削ぎ落とす
プロジェクトをアップデートする際、本当に「開発環境でしか使わないテストツール(PHPUnitなど)」の依存関係まで計算していませんか?
本番環境のデプロイ時や、純粋にプロダクションコードの依存関係だけを更新したい時は、`–no-dev` オプションを必ず使いましょう。
開発用パッケージ(require-dev)の依存関係解決をスキップして軽量化する
composer install –no-dev
【なぜこれでメモリが節約できるのか?】
Composerが計算するパッケージの数が、例えば `require` と `require-dev` 合せて200個あるとします。`–no-dev` を指定すると、開発用パッケージが計算対象からごっそり除外されるため、依存関係の組み合わせグラフが劇的に小さくなります。結果として、メモリ消費量を半分以下に抑えることができるのです。
—
解決策3:スワップ領域(仮想メモリ)を拡張する(ハードウェアの限界を超える最終手段)
もし、上記の方法を試しても、巨大なエンタープライズ向けのフレームワーク(Symfonyや大規模なLaravel構成など)を触っていて「どうしても物理メモリが足りない!」という場合は、OS側のスワップ領域(ディスクの一部をメモリに見せかける機能)を拡張しましょう。
特に、Docker環境(Laravel SailやMac/WindowsのDocker Desktop)で開発している場合、Dockerに割り当てられているメモリ上限が原因で落ちているケースが大半です。
- Docker Desktopの場合:
設定画面(Settings > Resources)を開き、Memoryの割り当てを最低でも `4GB` 以上に引き上げてください。これだけで嘘のようにエラーが出なくなります。
—
まとめ:もうメモリエラーに怯えないために
今回は、Composerで避けて通れない「Memory Exhausted」エラーの正体と、現場で確実に効く解決策について解説しました。
1. エラーの原因は、膨大なパッケージの依存関係を計算する際のメモリ不足。
2. 一時的または恒久的に `php -d memory_limit=-1` や `php.ini` で制限を外す。
3. `–no-dev` や Dockerのメモリ割り当てで見えない負荷を減らす。
このポイントさえ押さえておけば、どんなに巨大なプロジェクトを任されても、赤字のエラー画面に慌てふためくことはもうありません。
開発ツールの裏側の動きを少しだけ知ることで、毎日のコーディングや環境構築のストレスは劇的に軽くなります。快適なComposerライフを手に入れて、よりクリエイティブな実装に集中していきましょう!