miropen / mir-php
Fast static analyzer for PHP
Package info
Language:Rust
Type:composer-plugin
pkg:composer/miropen/mir-php
Requires
- php: >=8.1
- composer-plugin-api: ^2.0
Requires (Dev)
- composer/composer: ^2.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-main
- v0.99.0
- v0.98.0
- v0.97.0
- v0.96.0
- v0.95.0
- v0.94.0
- v0.93.0
- v0.92.0
- v0.91.0
- v0.90.0
- v0.89.0
- v0.88.0
- v0.87.0
- v0.86.0
- v0.85.0
- v0.84.0
- v0.83.0
- v0.82.0
- v0.81.0
- v0.80.0
- v0.79.0
- v0.78.0
- v0.77.0
- v0.76.0
- v0.75.0
- v0.74.0
- v0.73.0
- v0.72.1
- v0.72.0
- v0.71.0
- v0.70.1
- v0.70.0
- v0.69.0
- v0.68.0
- v0.67.0
- v0.66.1
- v0.66.0
- v0.65.0
- v0.64.0
- v0.63.0
- v0.62.0
- v0.61.0
- v0.60.0
- v0.59.2
- v0.59.1
- v0.59.0
- v0.58.0
- v0.57.0
- v0.56.0
- v0.55.1
- v0.55.0
- v0.54.0
- v0.53.1
- v0.52.0
- v0.51.0
- v0.50.2
- v0.50.1
- v0.50.0
- v0.49.0
- v0.48.0
- v0.47.0
- v0.46.0
- v0.45.0
- v0.44.0
- v0.43.0
- v0.42.0
- v0.41.0
- v0.40.0
- v0.39.0
- v0.38.0
- v0.37.0
- v0.36.0
- v0.35.1
- v0.35.0
- v0.34.0
- v0.33.0
- v0.32.0
- v0.31.0
- v0.30.0
- v0.29.0
- v0.28.0
- v0.27.0
- v0.26.0
- v0.25.0
- v0.24.0
- v0.23.0
- v0.22.0
- v0.21.2
- v0.21.1
- v0.21.0
- v0.20.0
- v0.19.0
- v0.18.0
- v0.17.3
- v0.17.2
- v0.17.1
- v0.17.0
- v0.16.2
- v0.16.0
- v0.15.0
- v0.14.0
- v0.13.0
- v0.12.0
- v0.11.1
- v0.11.0
- v0.10.0
This package is auto-updated.
Last update: 2026-11-12 14:51:52 UTC
README
mir
A fast, incremental PHP static analyzer written in Rust. It finds type errors, undefined symbols, dead code, injection vulnerabilities and many, many more without running your code. Why mir?
$ mir src/
src/demo.php:16:6 error[MIR0201] InvalidArgument: Argument $s of greet() expects 'string', got '42'
src/demo.php:18:0 error[MIR0004] UndefinedMethod: Method User::getName() does not exist
src/demo.php:21:0 error[MIR0802] TaintedSql: Tainted SQL query — possible SQL injection
= taint flow: $_GET['q'] (line 20) → $q (line 20)
Features
- 196 diagnostic rules with stable codes (
MIR0201): type errors, undefined symbols, nullability, arrays, generics, purity, dead code, taint and more. See the issue reference. - Type system: scalars, objects, generics and templates, unions, intersections, literals, array shapes,
class-string<T>, conditional return types,never,void. - Inference and narrowing: return types, literal narrowing,
if/match/switch/instanceof/is_*()/isset()guards, assertion annotations, and functions whose body is aninstanceofcheck. - Call checking: argument count, types, named arguments and by-reference parameters for user code and built-ins.
- Class analysis: inheritance, interface compliance, abstract enforcement, visibility,
readonly,final,#[Override], traits and enums. - Compile errors: code that parses but PHP rejects (
CompileError: trait conflicts, enum rules, invalidextends/implements), reported with PHP's wording for the target version. - Dead code (
--find-dead-code): unused variables, parameters, functions, classes, interfaces, traits and enums, plus private methods, properties and constants.@apiexempts public API. - Taint analysis: follows request data (
$_GET,$_POST, …) to HTML, SQL, shell, header, cookie, SSRF, LDAP, XPath, callable and LLM-prompt sinks, and prints the path it took. - PHP 7.4–8.6: code is parsed and checked at the target version (
--php-versionor<phpVersion>), including PHP 8.6 partial application. - Fast and incremental: parallel analysis over all CPUs; results are cached per file content hash, so unchanged files are skipped on re-runs.
- Plugins: native Rust plugins loaded as shared libraries.
- Built-in coverage: bundled JetBrains phpstorm-stubs for 77 extensions (2,500+ functions, 500+ classes), filtered by PHP version.
- CI output formats:
text,json,github-actions,junitandsarif. - Works with existing code: reads
@psalm-*and@phpstan-*annotations and suppressions as they are, plus Psalm config files, baselines and plugins. See Migrating to mir.
Installation
Composer (PHP projects)
composer require --dev miropen/mir-php vendor/bin/mir src/
A post-install-cmd hook downloads the prebuilt binary for your version and
platform from GitHub Releases and verifies its checksum. Binaries are published
for Linux (x86_64, aarch64), macOS (x86_64, Apple Silicon) and Windows (x86_64).
See the getting started guide.
crates.io
cargo install mir-php
From source
git clone https://github.com/jorgsowa/mir.git cd mir cargo build --release # binary at target/release/mir
Usage
mir # analyze the composer project in the current directory mir src/ lib/ # analyze specific paths mir --php-version 8.2 src/ # check against a specific PHP version mir --find-dead-code src/ # also report unused code mir --no-taint src/ # skip taint analysis mir --format sarif src/ > mir.sarif
mir picks up mir.xml from the current directory or any parent.
When a composer.json is found, the project files come from its autoload sections
and vendor code is loaded on demand. Exit code is 1 when any error is reported.
See the CLI reference and the configuration guide.
Baselines
Adopt mir on an existing codebase without fixing every issue first:
mir src/ --set-baseline # record current issues in mir-baseline.xml mir src/ # report only new issues mir src/ --update-baseline # drop entries for issues you fixed
Suppressing issues inline
Use @mir-ignore, @mir-ignore-next-line, or @mir-ignore-file to suppress a
false positive directly in source. @psalm-suppress and @phpstan-ignore-*
are accepted too. See the suppression reference.
GitHub Actions
Use the mir GitHub Action:
- uses: jorgsowa/mir-action@v1 with: path: src
Crates
| Crate | Purpose |
|---|---|
mir-php |
The mir command-line tool |
mir-analyzer |
Analysis engine: batch and incremental (salsa) analysis sessions |
mir-types |
Type representation and operations |
mir-codebase |
Definition types for classes, functions and constants |
mir-issues |
Issue kinds, codes and severities |
mir-plugin |
Plugin API and plugin loading |
mir-plugin-example |
Example Rust plugin |
mir-wasm |
WebAssembly build that powers the playground |
See the architecture overview.
Contributing
See CONTRIBUTING.md.
License
MIT