Introduction

Composer's platform requirements ensure that your project's dependencies are compatible with the installed PHP version and extensions. When running composer install or composer update, Composer checks that the current PHP version satisfies all require.php constraints in your dependency tree. A version mismatch error occurs when a package requires PHP 8.1+ but your server runs PHP 8.0, or when a required extension (like ext-gd or ext-intl) is missing. This error blocks deployment and can be difficult to resolve when multiple packages have conflicting PHP version requirements.

Symptoms

``` Your requirements could not be resolved to an installable set of packages.

Problem 1 - Root composer.json requires PHP extension ext-gd * but it is missing from your system. Install or enable PHP's gd extension.

Problem 2 - laravel/framework[v10.0.0, ..., v10.48.0] require php ^8.1 -> your php version (8.0.30) does not satisfy that requirement. ```

Or:

bash
Problem 1
    - symfony/console[v6.4.0, ..., v6.4.3] require php >=8.1 -> your php version (8.0.30) does not satisfy that requirement.
    - Root composer.json requires symfony/console ^6.4 -> satisfiable by symfony/console[v6.4.0, ..., v6.4.3].

Common Causes

  • Production PHP version older than development: Developing on PHP 8.2, deploying to PHP 8.0 server
  • Package upgraded beyond PHP compatibility: composer update pulled in a new major version requiring newer PHP
  • Missing PHP extension: Extension like ext-mbstring, ext-json, or ext-curl not installed
  • Platform config not matching production: Composer uses local PHP version to resolve, which differs from production
  • Transitive dependency requiring newer PHP: A direct dependency is compatible, but its sub-dependency is not
  • PHP EOL version: Using a PHP version that is end-of-life, with packages dropping support

Step-by-Step Fix

Step 1: Configure platform.php to match production

json
{
    "config": {
        "platform": {
            "php": "8.0.30",
            "ext-gd": "8.0.30",
            "ext-mbstring": "8.0.30",
            "ext-json": "*"
        }
    },
    "require": {
        "php": "^8.0",
        "laravel/framework": "^10.0"
    }
}

Then run:

bash
composer update --dry-run

This resolves dependencies as if running on PHP 8.0.30, catching incompatibilities before deployment.

Step 2: Install missing PHP extensions

```bash # Ubuntu/Debian sudo apt-get install php8.0-gd php8.0-mbstring php8.0-curl php8.0-xml

# RHEL/CentOS sudo yum install php-gd php-mbstring php-curl php-xml

# Verify php -m | grep gd ```

Step 3: Use polyfill packages for missing extensions

If you cannot install extensions:

bash
composer require symfony/polyfill-mbstring
composer require symfony/polyfill-php81
composer require symfony/polyfill-intl-normalizer

These packages provide fallback implementations of extension functions in pure PHP.

Step 4: Pin compatible package versions

```bash # Instead of composer update (which may pull incompatible versions) composer update laravel/framework --with-all-dependencies

# Or pin specific versions in composer.json { "require": { "laravel/framework": "^10.0 <10.30", "symfony/console": "^5.4" } } ```

Prevention

  • Always set config.platform.php to match your production PHP version
  • Run composer validate --strict in CI to catch platform issues before merge
  • Use composer install (not composer update) in production deployment
  • Pin PHP version in your CI environment to match production
  • Monitor package compatibility with composer outdated and plan PHP upgrades proactively
  • Document the minimum PHP version and required extensions in your project README