This release marks a major milestone for Mago, introducing the highly anticipated static analyzer. We've been working hard to bring you a powerful new tool to help you write better PHP code. This is the first alpha release of the 1.0.0 series, and we're excited to get it into your hands.
🚀 The Main Event: mago analyze
is Here!
The biggest new feature in this release is the mago analyze
command. This is a brand new, built-in static analyzer for PHP, designed to find bugs and improve code quality. It's fast, powerful, and easy to use.
⚠️ Experimental Feature Warning
The newmago analyze
command is highly experimental. It is a work in progress and you should expect it to have many false positives, potential panics, and other unexpected behavior. Please use it with caution and report any issues you find to our issue tracker.
📊 Initial Benchmark Results
We ran some initial benchmarks comparing the new analyzer against other popular PHP static analysis tools. These tests were performed on an M1 Macbook Pro
, analyzing the entire wordpress-develop
codebase.
Performance (Execution Time)

While Mago is the fastest of all, we are still not happy with the performance and are hoping to improve it further in the future. Our goal is to make static analysis feel instantaneous.
Resource Usage (Memory, Page Faults, Context Switches)

Memory usage is currently a problem, and Mago does use a lot of memory compared to other tools. We are actively working on fixing this issue by implementing more efficient data structures and codebase compilation techniques, and we hope to have more optimized releases soon.
📣 Breaking Changes
Pragma Directives Now Require a Category
With the introduction of the new mago analyze
command, we now have two components that can emit issues: the linter and the analyzer. To distinguish which tool an @mago-expect
or @mago-ignore
comment is targeting, you must now specify a category.
- Old:
@mago-expect best-practices/no-unused-parameter
- New:
@mago-expect lint:best-practices/no-unused-parameter
The available categories are:
- lint: for issues reported by the linter.
- analysis: for issues reported by the static analyzer.
Easy Migration Path
We understand that you might have many of these comments in your codebase. To make this transition painless, we've created a dedicated linter rule that will automatically add the lint:
category to all your existing, uncategorized pragmas.
To run the fixer, execute the following command:
mago lint --no-default-plugins --plugins comments --fix
To preview the changes first, add the --dry-run
flag.
💅 Polish & Paving the Way
While the analyzer was the main focus, we also squashed some important bugs and made a ton of improvements across the board:
🐞 Bug Fixes
- parser: Correctly handle fully qualified
use
statement prefixes. - parser: Handle large integer literals by parsing them as
float
. - parser: Correctly tokenize dynamic array keys in string interpolations.
- syntax: Fix CRLF heredoc parsing.
- formatter: Preserve closing echo tags.
- formatter: Ensure
clone
binary operations are correctly parenthesized. - formatter: Remove space between attribute and its associated parameter.
- stubs: Correct types and signatures for various built-in functions.
✨ Refactoring & Improvements
- linter: The
no-unused-parameter
rule is now much smarter. It correctly understands conditional blocks (if, while, etc.) and will no longer flag parameters as unused if they are only reassigned in a branch. - cli: Mago now supports PHP
8.5
and has adopted a rolling version policy for future PHP releases. - config: The configuration file is now also read from
$XDG_CONFIG_HOME
. - reporting: Added a new
ariadne
error reporting format. - stubs: The PHP extension stubs have been significantly cleaned up, consolidated, and improved for better type accuracy.
- deps: Updated various dependencies.
🛠️ For Rust API Users & Contributors
This release introduces several new crates for the analyzer infrastructure and removes others.
-
New Crates:
mago-analyzer
mago-algebra
mago-codex
mago-collector
mago-semantics
-
Removed Crates:
mago-project
mago-reflection
mago-typing
mago-trinary
⬆️ Updating
To update to this new version, simply run:
mago self-update
🧲 Pull Requests
- fix(formatter): Preserve closing echo tags by @edsrzf in #237
- feat(config): Also read configuration file from $XDG_CONFIG_HOME by @Zuruuh in #240
- fix(formatter): Ensure clone binary operations are correctly parenthesized by @Zuruuh in #243
- feat(analyzer): introduce experimental static analyzer by @azjezz in #248
- fix(syntax): CRLF heredoc parsing (#225) by @HenkPoley in #226
🤝 New Contributors
- @edsrzf made their first contribution in #237
- @HenkPoley made their first contribution in #226
Full Changelog: 0.26.1...1.0.0-alpha.1