mir

Getting Started

This guide walks you through installing mir, running your first analysis, and understanding the results.

Installation

cargo install mir-cli

Build from source

git clone --recurse-submodules https://github.com/jorgsowa/mir.git
cd mir
cargo build --release
# Binary is at target/release/mir

Important: The --recurse-submodules flag initializes the phpstorm-stubs submodule that provides PHP built-in definitions. Without it the build succeeds but mir will not recognise any PHP built-in functions, classes, or constants.

If you already cloned without it:

git submodule update --init

You can then copy the binary to a directory on your $PATH:

cp target/release/mir ~/.local/bin/

Basic usage

Point mir at one or more directories containing PHP source files:

mir src/

You can pass multiple paths:

mir application/library application/module public/

mir will recursively scan all .php files under the given paths and print any issues to stdout.

Targeting a PHP version

If your project targets a specific PHP version, pass --php-version:

mir --php-version 8.2 src/

Parallel analysis

By default mir uses all available CPU cores. To limit parallelism:

mir -j 4 src/

Understanding the output

Each issue is printed on one line with the format:

path/to/file.php:LINE:COL  IssueKind  message

For example:

src/Controller/UserController.php:42:5  UndefinedMethod  Method User::getName() does not exist
src/Service/Mailer.php:17:12  InvalidArgument  Argument 1 of sendMessage expects string, int provided

A non-zero exit code (1) means at least one issue was found; exit code 0 means the analysis is clean.

Issue kinds

The most common issue kinds you will encounter:

Kind What it means
UndefinedVariable A variable is used before it is assigned
UndefinedFunction A function call that has no definition
UndefinedMethod A method call on a type that does not have that method
UndefinedClass A class / interface / trait that does not exist
InvalidArgument A value passed to a function does not match the declared type
InvalidReturnType A function returns a type that does not match its declaration
PossiblyInvalidArrayAccess Array access on a value that may be false or null
NullableReturnStatement A nullable value returned from a non-nullable return type

See Issue Kinds for the full list.

Next steps

Use a configuration file

mir auto-discovers mir.xml or psalm.xml in the project root. You can also specify a config file explicitly:

mir -c psalm.xml src/

Suppress existing issues with a baseline

On large projects you may want to introduce mir without fixing every pre-existing issue at once. Generate a baseline file that records all current issues:

mir --set-baseline psalm-baseline.xml src/

On subsequent runs, pass the baseline to suppress those issues and only report new ones:

mir --baseline psalm-baseline.xml src/

When you fix issues, shrink the baseline so they are not re-introduced:

mir --update-baseline --baseline psalm-baseline.xml src/

CI integration

mir supports several output formats suited to CI environments:

# GitHub Actions inline annotations
mir --format github --no-progress src/

# JUnit XML (compatible with most CI systems)
mir --format junit src/ > results.xml

# SARIF (GitHub Code Scanning / VS Code)
mir --format sarif src/ > results.sarif

Incremental analysis

For large codebases, enable the incremental cache to speed up repeated runs:

mir --cache-dir .mir-cache src/

See the CLI Reference for the full list of options and the Docblock Annotations page for how to annotate your PHP code with type information.