> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/shivammathur/setup-php/llms.txt
> Use this file to discover all available pages before exploring further.

# Matrix Setup

> Run your PHP tests across multiple versions and operating systems using GitHub Actions matrix strategy.

A matrix strategy lets you run the same workflow job across multiple PHP versions, operating systems, and configurations in parallel. This is the most effective way to ensure your code works everywhere your users run it.

## Basic matrix example

The following workflow runs tests on Ubuntu, Windows, and macOS against PHP 8.2 through 8.5. Each combination becomes a separate job that runs in parallel.

```yaml theme={null}
jobs:
  run:
    runs-on: ${{ matrix.operating-system }}
    strategy:
      matrix:
        operating-system: ['ubuntu-latest', 'windows-latest', 'macos-latest']
        php-versions: ['8.2', '8.3', '8.4', '8.5']
        phpunit-versions: ['latest']
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php-versions }}
          extensions: mbstring, intl
          ini-values: post_max_size=256M, max_execution_time=180
          coverage: xdebug
          tools: php-cs-fixer, phpunit:${{ matrix.phpunit-versions }}

      - name: Install dependencies
        run: composer install --prefer-dist

      - name: Run tests
        run: phpunit
```

This produces 12 parallel jobs (3 operating systems × 4 PHP versions).

## Including specific PHP and PHPUnit version combinations

Use the `include:` key to add specific combinations that fall outside the main matrix. This is useful when you need to support an older PHP version that requires a pinned tool version.

```yaml theme={null}
jobs:
  run:
    runs-on: ${{ matrix.operating-system }}
    strategy:
      matrix:
        operating-system: ['ubuntu-latest', 'windows-latest', 'macos-latest']
        php-versions: ['8.2', '8.3', '8.4', '8.5']
        phpunit-versions: ['latest']
        include:
          - operating-system: 'ubuntu-latest'
            php-versions: '8.1'
            phpunit-versions: 10
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php-versions }}
          extensions: mbstring, intl
          ini-values: post_max_size=256M, max_execution_time=180
          coverage: xdebug
          tools: php-cs-fixer, phpunit:${{ matrix.phpunit-versions }}

      - name: Install dependencies
        run: composer install --prefer-dist

      - name: Run tests
        run: phpunit
```

The `include:` entry adds one extra job: PHP 8.1 on Ubuntu with PHPUnit 10. All other combinations use the `latest` PHPUnit version.

## Multi-arch setup

To run tests on both `amd64` and `arm64` architectures, use `shivammathur/node` container images. These images have compatible Node.js and PHP installed for `setup-php` on Ubuntu and Debian runners.

PHP 5.6 to PHP 8.5 are supported on multiple architectures through this approach.

```yaml theme={null}
jobs:
  run:
    runs-on: ${{ matrix.os }}
    container: shivammathur/node:php-${{ matrix.php-versions }}-24.04-${{ matrix.arch }}
    strategy:
      matrix:
        arch: ["amd64", "arm64v8"]
        php-versions: [8.4, 8.5]
        include:
          - arch: "amd64"
            os: "ubuntu-24.04"
          - arch: "arm64v8"
            os: "ubuntu-24.04-arm"
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php-versions }}

      - name: Install dependencies
        run: composer install --prefer-dist

      - name: Run tests
        run: phpunit
```

The container image tag format is `shivammathur/node:php-{version}-{ubuntu-version}-{arch}`. The `include:` entries map each architecture to the appropriate runner label.

## Matrix configuration tips

<AccordionGroup>
  <Accordion title="Disable fail-fast to see all results">
    By default, GitHub Actions cancels all in-progress jobs when one matrix job fails. Set `fail-fast: false` to let all jobs complete so you can see which combinations fail.

    ```yaml theme={null}
    strategy:
      fail-fast: false
      matrix:
        operating-system: ['ubuntu-latest', 'windows-latest', 'macos-latest']
        php-versions: ['8.2', '8.3', '8.4', '8.5']
    ```
  </Accordion>

  <Accordion title="Use exclude: to remove specific combinations">
    If certain combinations are not relevant (for example, PHP 5.x only on Linux), use `exclude:` to skip them and reduce job count.

    ```yaml theme={null}
    strategy:
      matrix:
        operating-system: ['ubuntu-latest', 'windows-latest', 'macos-latest']
        php-versions: ['8.3', '8.4', '8.5']
        exclude:
          - operating-system: 'windows-latest'
            php-versions: '8.3'
    ```
  </Accordion>

  <Accordion title="Name your jobs for readability">
    Add a `name:` field to the job to make the matrix jobs easier to identify in the Actions UI.

    ```yaml theme={null}
    jobs:
      run:
        name: PHP ${{ matrix.php-versions }} on ${{ matrix.operating-system }}
        runs-on: ${{ matrix.operating-system }}
    ```
  </Accordion>

  <Accordion title="Combine prefer-lowest with your matrix">
    Test both the minimum and stable versions of your Composer dependencies by adding a `prefer` dimension to your matrix. This is especially useful for libraries that need to support a range of dependency versions.

    ```yaml theme={null}
    strategy:
      matrix:
        php-versions: ['8.2', '8.3', '8.4']
        prefer: ['prefer-lowest', 'prefer-stable']
    steps:
      - name: Install dependencies
        run: composer update --${{ matrix.prefer }} --prefer-dist
    ```
  </Accordion>
</AccordionGroup>

<Tip>
  The GitHub-hosted runner label `ubuntu-latest` currently maps to Ubuntu 24.04. Pin to a specific version like `ubuntu-24.04` in production workflows to avoid unexpected changes when the `latest` label is updated.
</Tip>
