> ## 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.

# Problem Matchers

> Surface PHP errors, PHPUnit failures, and static analysis warnings as inline annotations in GitHub pull requests using problem matchers.

Problem matchers are JSON configuration files that tell GitHub Actions how to parse tool output and surface errors and warnings as inline annotations directly in pull requests and workflow run logs. They map log patterns to file paths and line numbers so reviewers can see issues without leaving the diff.

`setup-php` ships problem matcher files for PHP and PHPUnit inside the runner's tool cache. Additional tools like PHPStan and Psalm have native GitHub Actions output formats that work without a separate matcher file.

## PHP

The PHP problem matcher catches fatal errors, parse errors, and warnings in PHP output and links them to the corresponding source file and line.

Add this step immediately after the `setup-php` step:

```yaml theme={null}
- name: Setup problem matchers for PHP
  run: echo "::add-matcher::${{ runner.tool_cache }}/php.json"
```

## PHPUnit

The PHPUnit problem matcher highlights failing test cases in the workflow run log and annotates the test file at the failing assertion's line number.

Add this step after the `setup-php` step, before you run your tests:

```yaml theme={null}
- name: Setup problem matchers for PHPUnit
  run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
```

<Tip>
  You can activate both matchers in a single workflow to get annotations for both PHP runtime errors and PHPUnit failures.
</Tip>

## PHPStan

PHPStan has native GitHub Actions support built in. When it detects that it is running inside GitHub Actions it automatically emits annotations without requiring a problem matcher. No additional configuration is needed.

```yaml theme={null}
- name: Setup PHP
  uses: shivammathur/setup-php@v2
  with:
    php-version: '8.5'
    tools: phpstan

- name: Run PHPStan
  run: phpstan analyse src
```

## Psalm

Psalm supports GitHub Actions output via the `--output-format=github` flag. This emits annotations for every issue Psalm finds.

```yaml theme={null}
- name: Setup PHP
  uses: shivammathur/setup-php@v2
  with:
    php-version: '8.5'
    tools: psalm

- name: Run Psalm
  run: psalm --output-format=github
```

## Tools with checkstyle support

Several PHP tools can emit results in the checkstyle XML format: `phpcs`, `phpstan`, `psalm`, and `php-cs-fixer`. You can pipe that output into [`cs2pr`](https://github.com/staabm/annotate-pull-request-from-checkstyle), which converts checkstyle XML into GitHub Actions annotations.

Install `cs2pr` via the `tools` input and pipe checkstyle output to it:

<AccordionGroup>
  <Accordion title="phpcs with cs2pr">
    ```yaml theme={null}
    - name: Setup PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: '8.5'
        tools: cs2pr, phpcs

    - name: Run phpcs
      run: phpcs -q --report=checkstyle src | cs2pr
    ```
  </Accordion>

  <Accordion title="php-cs-fixer with cs2pr">
    ```yaml theme={null}
    - name: Setup PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: '8.5'
        tools: cs2pr, php-cs-fixer

    - name: Run php-cs-fixer
      run: php-cs-fixer fix --dry-run --format=checkstyle | cs2pr
    ```
  </Accordion>

  <Accordion title="phpstan with cs2pr">
    ```yaml theme={null}
    - name: Setup PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: '8.5'
        tools: cs2pr, phpstan

    - name: Run PHPStan
      run: phpstan analyse --error-format=checkstyle src | cs2pr
    ```
  </Accordion>

  <Accordion title="psalm with cs2pr">
    ```yaml theme={null}
    - name: Setup PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: '8.5'
        tools: cs2pr, psalm

    - name: Run Psalm
      run: psalm --output-format=checkstyle | cs2pr
    ```
  </Accordion>
</AccordionGroup>

<Note>
  `cs2pr` exits with a non-zero status code when it finds issues, which causes the workflow step to fail as expected. Refer to the [cs2pr documentation](https://github.com/staabm/annotate-pull-request-from-checkstyle) for additional options such as filtering by severity or graceful-warnings mode.
</Note>

## Combining matchers in a workflow

The example below shows a complete workflow that activates both the PHP and PHPUnit problem matchers alongside PHPStan's native annotations:

```yaml theme={null}
name: CI
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v6

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.5'
          extensions: mbstring
          tools: phpstan
          coverage: xdebug

      - name: Setup problem matchers for PHP
        run: echo "::add-matcher::${{ runner.tool_cache }}/php.json"

      - name: Setup problem matchers for PHPUnit
        run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"

      - name: Install Composer dependencies
        run: composer install --no-progress --prefer-dist

      - name: Run PHPStan
        run: phpstan analyse src

      - name: Run tests
        run: vendor/bin/phpunit --coverage-text
```
