Composerの「Your requirements could not be resolved」の読み方|Problemの行から原因を特定し、why-not・check-platform-reqs・-Wで解決する手順

技術ノウハウ

※本記事にはアフィリエイト広告が含まれます。

Laravelやライブラリのバージョンを上げようとして composer update や composer require を実行したら、依存関係を解決できないというエラーで止まり、長い英文のどこを読めばよいかわからない。PHPの案件ではよくある場面です。

この記事では、このエラーの原因を「何を確かめればよいか」「どのコマンドで調べるか」「どう直すか」の順に整理します。コマンドやオプションの説明は、2026-10-16時点のComposer公式ドキュメント(getcomposer.org)の記述にもとづきます。エラーメッセージの文面や書式は公式ドキュメントに全文の例がなく、Composerのバージョンや環境によっても変わりうるため、この記事では扱いません。エラー文の解釈に頼らず、公式のコマンドで原因を確かめる手順に絞って解説します。

結論:エラー文を読み解くより、why-notとcheck-platform-reqsで原因を確かめる

依存関係が解決できないときに突き止めたいのは、次の3点です。

  • 要求しているのは誰か(ルートのcomposer.jsonか、依存先のパッケージか)
  • 要求されているのは何か(php、ext-*、ほかのパッケージ)
  • どのバージョン範囲か(^8.3、~1.2 など)

この3点は、エラー文から推測するよりも composer why-not(prohibits)で確かめるほうが確実です。公式ドキュメントでは、prohibits は「指定したパッケージのインストールを阻んでいるパッケージ」を表示するコマンドとされ、例として laravel/framework v5.2.16 requires symfony/var-dumper (2.8.*|3.0.*) のように、要求元・要求対象・バージョン範囲がそろった出力が示されています。

最短の流れは次のとおりです。

  1. composer why-not <パッケージ> <バージョン> で、入れたいバージョンを阻んでいるパッケージを特定する
  2. 阻んでいるパッケージの制約を見直す(そのパッケージも一緒に上げられるか、ルートの制約を変えるか)
  3. 必要なら -w / -W で更新範囲を広げて、対象とブロッカーだけを更新する
  4. PHPや拡張が原因なら、composer check-platform-reqs で実際の環境が要件を満たしているか確認する

前提:^と~のバージョン制約、stabilityの意味

why-notの結果やcomposer.jsonの制約を読み違えないよう、よく使われる2つの演算子とstabilityを先に押さえておきます。

^(キャレット)と~(チルダ)

制約意味
^1.2.3>=1.2.3 <2.0.0
^0.3>=0.3.0 <0.4.0(1.0未満は安全側に倒して扱う)
~1.2>=1.2 <2.0.0
~1.2.3>=1.2.3 <1.3.0

注意したいのは ^0.x です。公式ドキュメントでは、1.0未満のバージョンについて ^0.3 を >=0.3.0 <0.4.0 として扱うと説明されています。0系のライブラリはマイナーバージョンが変わるだけで範囲外になるので、「少し上げるだけなのに解決できない」ときはここを疑います。また ~1.2 と ~1.2.3 は、桁数によって上限が変わる点も見落としやすいところです。

stability(安定度)

Composerが認識するstabilityは、安定度の低い順に dev・alpha・beta・RC・stable です。バージョンのstabilityはサフィックスで決まり、v1.1 のようにサフィックスがなければstableとして扱われます。

ルートのcomposer.jsonの minimum-stability は既定で stable です。betaやRCのバージョンを入れたい場合は、minimum-stability を変えるか、"monolog/monolog": "1.0.*@beta" のようなstabilityフラグでパッケージ単位に許可します。stabilityフラグはルートパッケージでのみ使えます。

原因のパターン別:何を確認し、どのコマンドで調べるか

PHPのバージョンが合わない

あるパッケージの新しいバージョンが、手元のPHPより新しいPHPを要求している(あるいは逆に、古いパッケージが新しいPHPへの対応を宣言していない)パターンです。LaravelのメジャーアップグレードやPHPの移行のときに起きやすい組み合わせです。

PHPを上げる前提なら、composer why-not php <バージョン> のように、移行先のPHPバージョンを阻んでいるパッケージを洗い出せます。prohibits(別名 why-not)は、指定したパッケージのインストールを阻んでいるパッケージを表示するコマンドです。

ext-* が足りない

パッケージが ext-intl や ext-gd のような拡張を要求していて、手元のPHPにその拡張がないパターンです。基本の対処は、その拡張をPHPに入れて有効にすることです。Dockerを使っている場合は、ローカルのPHPではなくコンテナ内のPHPで確認します。

--ignore-platform-req=ext-foo のように特定の要件だけを無視してインストールすることもできますが、後述のとおりこれは「チェックを飛ばす」だけです。拡張を使う処理は実行時に失敗しうるので、一時的な回避にとどめます。

ルートの制約と他パッケージの制約が衝突している

「ルートのcomposer.jsonでは A を ^2.0 で要求しているが、パッケージ B は A の ^1.0 を要求している」というように、2か所の要求の範囲に重なりがないパターンです。

composer why-not <パッケージ> <バージョン> でブロッカーを特定します。依存が何段にもなっている場合は、--recursive(-r)でルートパッケージまで遡って解決するか、--tree(-t、-r を含む)で入れ子のツリーとして表示できます。逆に「このパッケージを誰が必要としているか」を知りたいときは depends(別名 why)を使います。

公式のTroubleshootingでも、パッケージが期待したバージョンに更新されないときは why-not [package-name] [expected-version] を実行するよう案内されています。

パッケージが見つからない

要求したパッケージやバージョン自体が見つからないパターンです。公式Troubleshootingの「Package not found」では、主な確認点として次が挙げられています。

  • composer.jsonやリポジトリのブランチ名・タグ名にタイプミスがないか
  • minimum-stability が正しく設定されているか
  • Packagist以外から取得するパッケージは、ルートパッケージで定義しているか
  • リポジトリのすべてのブランチ・タグで同じベンダー名・パッケージ名を使っているか
  • Packagistでは新しいパッケージがComposerから見えるまで最大1分の遅れがある
  • 1つのパッケージだけを更新している場合は、--with-dependencies を付けるか、更新が必要な依存もすべてコマンドに加える

早見表

原因のパターン見る箇所調べるコマンド・設定
PHPのバージョンが合わない手元・本番のPHPバージョン、config.platformwhy-not php <バージョン>、check-platform-reqs
ext-* が足りないPHPの拡張の有効化状況(コンテナ内も)check-platform-reqs
パッケージ同士の制約の衝突ルートのcomposer.jsonの制約、依存先の制約why-not <パッケージ> <バージョン>(-r / -t)、why
パッケージ・バージョンが見つからない名前のタイプミス、minimum-stability、リポジトリ定義stabilityフラグ、Troubleshootingの確認点

更新範囲の広げ方:–with-dependencies(-w)と–with-all-dependencies(-W)

ブロッカーがわかったら、多くの場合は「対象のパッケージと一緒に、その依存も上げる」必要があります。composer update には更新範囲を広げる2つのオプションがあり、違いはルート要件(ルートのcomposer.jsonに直接書いたパッケージ)を含むかどうかです。

オプション公式ドキュメントの説明(要約)
--with-dependencies(-w)引数に指定したパッケージの依存も更新する。ただしルート要件は除く
--with-all-dependencies(-W)引数に指定したパッケージの依存も更新する。ルート要件も含む

composer require にも同じ考え方の --update-with-dependencies(-w)と --update-with-all-dependencies(-W)があり、新しく要求したパッケージの依存を、ルート要件を除いて/含めて更新します。

ブロッカーがルートのcomposer.jsonに直接書いたパッケージなら -w では動かせないので -W が必要、間接的な依存だけなら -w で足りる、と使い分けます。いきなり引数なしの composer update で全体を更新すると、関係のないパッケージまで一度に上がり、問題が起きたときに原因を切り分けにくくなります。まず composer update vendor/target vendor/blocker -W のように対象とブロッカーだけを指定して更新し、composer.lockの差分を確認してから進めるのがおすすめです。

最終手段:インラインエイリアス

依存先のパッケージAがBの0.1を要求しているが、自分はBの0.11を使いたい、という場合、公式Troubleshootingでは "B": "0.11 as 0.1" のようにエイリアスで解決する方法が紹介されています。

ただしAliasesのドキュメントでは、インラインエイリアスはルートパッケージでのみ機能する機能であり、特に公開するパッケージ・ライブラリでは避けるべきで、バグを見つけた場合はアップストリームへの修正の取り込みを目指すよう書かれています。実際には互換性を宣言していないバージョンを「互換がある」とみなさせる方法なので、最後の手段と考えてください。

よくある誤解:platform設定や–ignore-platform-reqsで「通った」は解決ではない

PHPや拡張が原因のエラーは、設定やオプションで「通す」ことができます。ただしどれも依存関係のチェックを緩めるだけで、実行環境の問題は残ります。副作用を公式の記述で確認しておきます。

config.platform は「本番の模擬」だが、チェックが正しく行われなくなる

config.platform は、PHPや拡張のバージョンを偽装して本番環境を模擬する(あるいは対象のプラットフォームを定義する)ための設定です。公式の例では {"php": "7.0.3", "ext-something": "4.0.3"} と書くと、ローカルで実際に動いているPHPのバージョンにかかわらず、PHP 7.0.3より新しいPHPを要求するパッケージはインストールされなくなります。

一方で公式は、これによって依存関係が正しくチェックされなくなると警告しています。例として、実際にはPHP 5.6で動かしていても7.0.3とみなすのでインストールは通るが、実行時に失敗する、と書かれています。そのため、この設定を使う場合はデプロイの手順に check-platform-reqs も組み込むことが推奨されています。

check-platform-reqs は config.platform を無視して実際の環境を見る

composer check-platform-reqs は、update/installと違って config.platform の設定を無視します。つまり「偽装した値」ではなく、実行している環境のPHPと拡張が要件を満たしているかを確認できます。--lock でインストール済みパッケージではなくロックファイルの要件だけを確認でき、--no-dev でrequire-devの要件を確認対象から外せます。

–ignore-platform-reqs と –ignore-platform-req=php+

--ignore-platform-reqs は php・hhvm・lib-*・ext-* のすべてのプラットフォーム要件を無視し、ローカル環境が満たしていなくてもインストールを強行します。--ignore-platform-req は特定の要件だけを無視します。

install・updateのドキュメントでは、末尾に + を付けると要件の上限だけを無視すると説明されています。たとえば php: ^7 を要求するパッケージに対して --ignore-platform-req=php+ を付けるとPHP 8へのインストールは許可されますが、PHP 5.6へのインストールは引き続き失敗します。「パッケージが新しいPHPへの対応を宣言していないだけ」の場面で、下限のチェックは残したまま試すための指定です。それでも、そのパッケージが新しいPHPで動く保証にはなりません。

platform-check の既定は php-only

Composerはオートローダーの読み込み時に platform_check.php で実行環境を確認します。設定 platform-check の既定値は php-only で、PHPのバージョンだけを確認します。true にすると拡張の有無も確認し、false にすると platform_check.php を作りません。つまり既定のままでは、拡張が足りないことは実行時のチェックでは検出されません。拡張の不足を見逃さないためにも、check-platform-reqs を明示的に実行する意味があります。

まとめ

Composerで依存関係が解決できないときのチェックリストです。

  • 要求元・要求対象・バージョン範囲の3点を突き止める(エラー文の推測より why-not の結果を優先する)
  • ^0.x や ~1.2.3 の上限、minimum-stability(既定はstable)を読み違えていないか確認する
  • why-not <パッケージ> <バージョン> でブロッカーを特定する(必要なら -t)
  • ブロッカーがルート要件なら -W、間接依存だけなら -w で、対象を絞って更新する
  • config.platform や --ignore-platform-req で通した場合は、check-platform-reqs で実際の環境を確認する

依存関係の衝突は、LaravelのメジャーアップグレードやPHPのバージョン移行のときに起きやすいものです。Laravel 12から13へ上げる場合の変更点はLaravel 12から13へのアップグレードガイド、PHP 8.2からの移行先の選び方はPHP 8.2のサポート終了と移行先の比較にまとめています。

Composerの依存管理やPHPのバージョンアップを体系的に学び直したい場合は、PHPの実践的な技術書を1冊手元に置いておくと、公式ドキュメントと行き来しながら理解を深められます。

Amazonで「PHP 本」を探す

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