README 只给出 macOS 和 Linux 的 shell 脚本安装方式,Windows 及其他方式需查官方安装指南;安装脚本默认装最新版,要固定版本需加 --version 参数;具体配置与上手步骤在官方文档站,README 未展开
mago
carthage-softwareApache-2.0活跃维护用 Rust 写的 PHP 工具链,集代码格式化、静态分析、类型检查和 lint 于一体,帮开发者统一代码风格、提前发现潜在问题。
Mago is a toolchain for PHP that aims to provide a set of tools to help developers write better code.
curl --proto '=https' --tlsv1.2 -sSf https://carthage.software/mago.sh | bashREADME 未说明硬件要求;工具用 Rust 编写,通过 shell 脚本安装,未提及 GPU 或显存需求
用 Rust 写的 PHP 工具链,把 lint、格式化、静态分析合成一个极快的命令行工具
用 Rust 写的 PHP 工具链,集代码格式化、静态分析、类型检查和 lint 于一体,帮开发者统一代码风格、提前发现潜在问题。
核心能力
- 用 Rust 实现,主打极快的执行速度
- 可配置规则检查代码问题并自动修复多数 lint 问题
- 对代码库做深度静态分析,捕捉类型错误与潜在 bug
- 按最佳实践和风格指南自动格式化代码
- 支持语义检查与 CST 语法树可视化
容易踩的坑
- 1.59.0Mago 1.59.0最新正式版2026-10-25 · 2026-10-25 01:05 UTC
Mago 1.59.0 fixes analyzer narrowing across boolean guards, nullsafe checks, and
elseifbranches, improves generic and callable inference, and updates the analyzer extension protocol to MANA 2.2.[!NOTE]
Support Mago
Does your company use Mago? Please consider sponsoring its development so we can keep fixing bugs and shipping releases.
Sponsor Mago ❤️
🐛 Bug Fixes
Analyzer
- Namespace constants: preserves global constant fallback in namespaced declarations. (#2594, 0e6c1d8)
- Method assertions: keeps getter assertions from the right side of
||. (#2600, #2609, 777429f) - CLI argument guards: fixes
$argctyping and negatedcount()bounds. (#2607, #2608, be88d13) - Template defaults: applies declared defaults when constructing generic objects. (#2603, #2606, 2066b18)
- Stored booleans: keeps narrowing implied by boolean variables across
&&and||. (#2601, 8d739b3) - Nullsafe membership: narrows receivers after strict
in_array()checks against non-null values. (#2599, 56e4b49) - Collection intersections: honors narrower read types in intersected collection types. (#2612, 79c295f)
- Callable signatures: preserves parameter and return types through
Closure::fromCallable(). (#2611, #2614, 3ea5963) - PHPDoc generics: checks missing, excess, and out-of-bounds template arguments in docblocks. (#2616, 2ac5c5d)
- Boolean branches: preserves
trueandfalsetypes across short-circuit expressions. (#2593, 9890d23) - Dynamic instanceof: keeps valid operand types when a dynamic class check fails. (#2592, #2595, 65530ba)
- Strict equality: narrows both union-typed operands to their shared types. (#2559, 923c061)
- Elseif branches: preserves all reachable types and branch facts after conditional chains. (#2619, 0a098f4)
- Nullsafe comparisons: avoids false impossible-null reports when assigning comparison results. (#2591, b7273f4)
- URL components: allows empty user, password, query, and fragment strings from
parse_url(). (#2590, #2610, 16dd70b)
📖 Documentation
Extensions
- Protocol compatibility: documents MANA 2.2 constant fallback and worker upgrade requirements. (#2594, 0e6c1d8)
🏗️ Internal
CI
- Pull request limit: limits outside contributors to one open PR at a time, including drafts. (9b6979c)
Tooling
- Justfile cleanup: removes an unused variable. (3f212f3)
🧩 Extension Protocol
Analyzer
- MANA 2.2: adds namespace fallbacks to global constant references in the protocol and PHP SDK. (#2594, 0e6c1d8)
Update the PHP SDK to 1.59.0 when upgrading Mago. Custom analyzer workers must use MANA 2.2; MANA 2.1 workers are not compatible. The linter protocol is unchanged.
🙏 Thank You
Contributors
Thank you to everyone who contributed to this release:
- @alfredbez: #2559
- @hbenabdallah: #2595
- @pujitha24: #2610
- @shuvroroy: #2606, #2608, #2609, #2614
- @serdarucel for investigating #2591 in #2598.
Issue Reporters
Thank you to everyone who reported issues that shaped this release:
- @alfredbez: #2619
- @cweiske: #2611
- @douglasgreen: #2607
- @gsteel: #2593
- @MichaelOwenDyer: #2591, #2592, #2599, #2600, #2601
- @NoNoNo: #2594
- @norberttech: #2616
- @npo-mmenke: #2603, #2612
- @patka-123: #2590
Full Changelog: https://github.com/carthage-software/mago/compare/1.58.2...1.59.0
- 1.58.2Mago 1.58.22026-10-19 · 2026-10-19 20:43 UTC
查看更新说明
Mago 1.58.2 fixes parser recovery for unfinished static accesses, keeping class names and call arguments in the syntax tree while you type.
[!NOTE]
Support Mago
Does your company use Mago? Please consider sponsoring its development so we can keep fixing bugs and shipping releases.
Sponsor Mago ❤️
🐛 Bug Fixes
Parser
- Incomplete static access: keeps
Foo::andFoo::$in the syntax tree during editor recovery. (#2589, 431e823)
🙏 Thank You
Contributors
- @azjezz for the parser fix. (431e823)
Issue Reporters
- @AJenbo for reporting #2589.
Full Changelog: 1.58.1...1.58.2
- Incomplete static access: keeps
- 1.58.1Mago 1.58.12026-10-19 · 2026-10-19 20:03 UTC
查看更新说明
Mago 1.58.1 fixes the PGO build failure affecting macOS and Linux x86_64 musl in 1.58.0 and adds CI checks for the full PGO build cycle.
[!NOTE]
Support Mago
Does your company use Mago? Please consider sponsoring its development so we can keep fixing bugs and shipping releases.
Sponsor Mago ❤️
🐛 Bug Fixes
CLI
- Profiling output: preserves PGO and coverage profiles at shutdown, fixing affected release builds. (c8ad3d0)
🏗️ Internal
CI
- PGO builds: checks profile output and optimized binaries on Linux musl and both macOS targets. (c8ad3d0)
🙏 Thank You
Contributors
- @azjezz for the build fix and PGO checks. (c8ad3d0)
Issue Reporters
Thanks for your patience while we fixed the release builds.
Full Changelog: https://github.com/carthage-software/mago/compare/1.58.0...1.58.1
- 1.58.0Mago 1.58.02026-10-19 · 2026-10-19 19:23 UTC
查看更新说明
Mago 1.58.0 adds opt-in dead-catch checks, a
prefer-selfrule, and extension throw-type providers, cuts analysis overhead, and fixes type narrowing and PHP formatting.[!NOTE]
Support Mago
Does your company use Mago? Please consider sponsoring its development so we can keep fixing bugs and shipping releases.
Sponsor Mago ❤️
✨ Features
Analyzer
- Dead catches: adds opt-in checks for catches with no known matching throws. (#2503, #2525, 18315f6)
- Enum throws: avoids
ValueErrorfor known-validBackedEnum::from()arguments. (#2544, #2565, 5bcf444)
Linter
- Prefer self: adds an opt-in rule to replace references to the enclosing class with
self. (#2528, aba4df1) - Extension rules: accepts enabled, level, and exclude settings under
[linter.rules]. (#2530, f2b479c)
🐛 Bug Fixes
Analyzer
- Named arguments: honors class-level
@no-named-argumentstags. (#2514, a33b014) - Mixed array keys: reports
mixed-array-indexfor keys whose type is mixed. (#2522, 4b19550) - Nullsafe guards: narrows receivers through guards and falsy
??fallbacks. (#2515, #2563, 83a0bfd, 891c463) - Do-while loops: preserves initial types when by-reference calls update loop variables. (#2523, b6a24d9)
- Diagnostics: clarifies class resolution, member access, and type-check messages. (#2541, 43f0a1a)
- Redundant nullsafe calls: reports unnecessary
?->on method calls. (#2547, ba38156) - Iterable guards: narrows iterable values to
Traversableafter type checks. (#2550, dd17cfb) - Match assignments: preserves subject types and evaluates assignment subjects once. (8a19e98)
- Shape unions: removes shapes with required keys after a failed key-existence check. (#2557, 5ffc5d2)
- Nested array guards: keeps required keys when narrowing nested shapes. (#2577, 221fd63)
- Type switches: narrows variables in
get_class()andgettype()switch cases. (#2558, eba91e1) - Callable guards: fixes narrowing of callable objects and strings in type checks. (#2552, #2560, 0e1d212, abea0ad)
- Conditional assignments: keeps assignments scoped to each analysis pass. (#2561, 64a2323)
- Short-circuit assignments: tracks reassignment and narrowing across logical chains. (#2571, #2562, c8358f1, 001666b)
- Array membership: fixes strict checks and unsafe narrowing after negated
in_array(). (#2573, #2574, d5ca2a6, c16337a) - Known array keys: resolves literal keys in
isset()andempty()guards. (#2575, #2585, 9671d89, f8f46a6) - Numeric-string keys: normalizes integer-like string keys in array guards. (#2578, d7dae70)
- Loose null checks: preserves falsy strings when comparing nullable strings with null. (#2579, ff5df16)
- Negated isset: does not treat nullable keys as missing after a failed check. (#2554, #2576, fb8de05)
- Switch transfers: preserves nested breaks, continues, and finally control flow. (#2569, #2570, b6e8259)
- Empty foreach loops: skips unreachable loop bodies for known empty arrays. (#2572, 6bdf6c6)
- Switch coverage: detects impossible cases and unreachable defaults. (#2553, 204f678)
Codex
- Large unions: expands types beyond 64 members without leaving unresolved references. (#2518, 51f2762)
- Traversable templates: keeps caller templates instead of widening them to their bounds. (#2520, 735d59d)
- Class strings: handles leading backslashes when comparing literal class names. (#2533, 1a28236)
- Iterable arguments: rejects excess generic arguments on iterable types. (#2543, 1c3eba0)
- Mixed array keys: treats explicit mixed key types as
array-key. (#2545, c4d7f9a)
PHPDoc
- Array shorthand: accepts spaces between a type and its
[]suffix. (#2546, 00c150d)
Formatter
- Preserved breaks: keeps argument-list and binary-expression layouts stable across passes. (#2524, e665c18)
- Instanceof calls: preserves required parent
- 1.57.0Mago 1.57.02026-10-14 · 2026-10-14 07:33 UTC
查看更新说明
Mago 1.57.0 adds opt-in BcMath/GMP arithmetic, applies PHPDoc flags from type patches, fixes analyzer and formatter bugs, and speeds up work across the toolchain.
[!NOTE]
Support Mago
Does your company use Mago? Please consider sponsoring its development so we can keep fixing bugs and shipping releases.
Sponsor Mago ❤️
✨ Features
Analyzer
- Number operators: adds opt-in arithmetic for
BcMath\NumberandGMPviaallow-operator-overloading. (#2486, #2487, 0fff359)
🐛 Bug Fixes
Analyzer
- Native type contracts: keeps native types and nullability when PHPDoc conflicts. (#2494, 2dc705f)
- Inline @var tags: no longer treats unassigned local variables as defined. (#2496, 56f2ad9)
- Malformed PHPDoc: reports malformed types and unresolved variable links. (#2493, c1cdff1)
- Conditional variables: reports possibly undefined variables after switch and in finally. (#2497, e378e5d)
- Iterator types: keeps current() and key() types without explicit generics. (#2476, 467b29d)
- Array unions: preserves left-hand values and optional keys with array-key key types. (#2485, #2488, 782b0b5)
- Empty checks: handles unset variables and falsy values correctly. (#2484, 8dc47c5)
- Dynamic properties: honors AllowDynamicProperties on classes and their ancestors. (#2483, 6bccb58)
- Deprecated members: reports access to deprecated properties and class constants. (#2478, 90fa5e5)
- Deprecated scopes: skips deprecation warnings inside already deprecated code. (#2492, d412c32)
- Boolean assignments: avoids false narrowing when loops update boolean flags. (#2499, 64ad7d6)
- Iterable assertions: narrows traversables without false impossible-condition reports. (#2508, ac54e6c)
Codex
- Patch flags: applies supported PHPDoc flags and their negations from type patches. (#2477, #2495, 29f3416)
Formatter
- Stable layouts: keeps concatenations, arrow functions, and assignments stable across passes. (#2491, 9f4804d)
- Parenthesized comparisons: keeps comparison layouts stable when operands use parentheses. (#2480, f2fdf5f)
Prelude
- Base64 decoding: returns string for non-strict decoding. (#2511, 4918783)
📖 Documentation
Configuration
- Operator settings: documents opt-in number operators in English, French, and Chinese. (#2487, 0fff359)
- Patch flags: documents supported PHPDoc patch flags in English, French, and Chinese. (#2495, 29f3416)
🏗️ Internal
Analyzer
- Named arguments: speeds up argument matching and default type inference. (#2498, 2f7475f)
- Member checks: cuts reference scans and allocations when checking unused members. (cc19617)
- Default arguments: skips needless type expansion for omitted non-generic defaults. (#2506, #2507, 6590a7b)
Codex
- Reference lookups: speeds up reference queries and merges. (23ebbf2)
Formatter
- Formatting work: cuts allocations and layout work. (a2e8ae5)
Guard
- Dependency scans: skips unused dependency files and cuts allocations. (dae8785)
🧩 Extension Protocol
No protocol changes in this release.
🙏 Thank You
Contributors
Thank you to everyone who contributed to this release:
- @alfredbez: #2476, #2492, #2493, #2494, #2496, #2497, #2511
- @AnnaDamm: #2495, #2507
- @matthewnessworthy: #2480
- @Mir-Zairan: #2487
- @ynaamane: #2488
Issue Reporters
Thank you to everyone who reported issues that shaped this release:
- @amateescu: #2478, #2508
- @AnnaDamm: #2477, #2498, #2506
- @atournayre: #2491
- @jfilter: #2483, #2484, #2485
- @MichaelOwenDyer: #2499
- @Mir-Zairan: #2486
Full Changelog: https://github.com/carthage-software/mago/compare/1.56.3...1.57.0
- Number operators: adds opt-in arithmetic for
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
An extremely fast PHP linter, formatter, and static analyzer, written in Rust.
Mago is a comprehensive toolchain for PHP that helps developers write better code. Inspired by the Rust ecosystem, Mago brings speed, reliability, and an exceptional developer experience to PHP projects of all sizes.
Table of Contents
- Installation
- Getting Started
- Features
- Our Sponsors
- Contributing
- Inspiration & Acknowledgements
- License
Installation
The most common way to install Mago on macOS and Linux is by using our shell script:
curl --proto '=https' --tlsv1.2 -sSf https://carthage.software/mago.sh | bash
To install a specific version:
curl --proto '=https' --tlsv1.2 -sSf https://carthage.software/mago.sh | bash -s -- --version=1.59.0
For all other installation methods, including Homebrew, Composer, and Cargo, please refer to our official Installation Guide.
Getting Started
To get started with Mago and learn how to configure your project, please visit our Getting Started Guide in the official documentation.
Features
- ⚡️ Extremely Fast: Built in Rust for maximum performance.
- 🔍 Lint: Identify issues in your codebase with customizable rules.
- 🔬 Static Analysis: Perform deep analysis of your codebase to catch potential type errors and bugs.
- 🛠️ Automated Fixes: Apply fixes for many lint issues automatically.
- 📜 Formatting: Automatically format your code to adhere to best practices and style guides.
- 🧠 Semantic Checks: Ensure code correctness with robust semantic analysis.
- 🌳 CST Visualization: Explore your code’s structure with Concrete Syntax Tree (CST) parsing.
Our Sponsors
Contributing
Mago is a community-driven project, and we welcome contributions! Whether you're reporting bugs, suggesting features, writing documentation, or submitting code, your help is valued.
- See our Contributing Guide to get started.
- Join the discussion on Discord.
Inspiration & Acknowledgements
Mago stands on the shoulders of giants. Our design and functionality are heavily inspired by pioneering tools in both the Rust and PHP ecosystems.
Inspirations:
- Clippy: For its comprehensive linting approach.
- OXC: A major inspiration for building a high-performance toolchain in Rust.
- Hakana: For its deep static analysis capabilities.
Acknowledgements:
We deeply respect the foundational work of tools like PHP-CS-Fixer, Psalm, PHPStan, and PHP_CodeSniffer. While Mago aims to offer a unified and faster alternative, these tools paved the way for modern PHP development.
License
Mago is dual-licensed under your choice of the following:
- MIT License (LICENSE-MIT)
- Apache License, Version 2.0 (LICENSE-APACHE)