README 未说明具体依赖版本,安装前需查阅安装指南文档
psalm
vimeoMIT活跃维护PHP 静态分析工具,通过类型推断和污点分析在运行前发现代码错误与安全漏洞,适合 CI 中做质量门禁。
A PHP static analysis tool for finding errors and security vulnerabilities in PHP applications
README 未给出具体命令,安装步骤见 docs/running_psalm/installation.mdREADME 未说明
PHP 静态分析工具,帮你在运行前找出代码错误和安全隐患
PHP 静态分析工具,通过类型推断和污点分析在运行前发现代码错误与安全漏洞,适合 CI 中做质量门禁。
核心能力
- 静态分析 PHP 代码,无需运行即可发现错误
- 可检测安全漏洞类问题
- 提供在线 Demo 可直接试用
- 文档托管在 psalm.dev 官网
容易踩的坑
- 7.2.0最新正式版2026-11-09 · 2026-11-09 10:27 UTC
What's Changed
Features
- Report
HiddenGeneratorReturnfor a value a generator returns through a type without Generator by @alies-dev & @azjezz in https://github.com/vimeo/psalm/pull/13485
Fixes
- fix(docblock): check the classes of @global types by @jirkace in https://github.com/vimeo/psalm/pull/13170
- Fix: static bound to a receiver is bound again on every call inside a template argument (also fixes OOM) by @alies-dev in https://github.com/vimeo/psalm/pull/13442
- Fix: show the auto-fix suggestion footer when taint analysis runs by @alies-dev in https://github.com/vimeo/psalm/pull/13450
- fix(types): combining object shapes keeps the properties of both by @jirkace in https://github.com/vimeo/psalm/pull/13444
- fix(stubs): the inner iterator template of the SPL iterator wrappers has a default by @jirkace in https://github.com/vimeo/psalm/pull/13443
- fix(types): a narrower native return type wins over an inherited docblock with a __toString coercion by @jirkace in https://github.com/vimeo/psalm/pull/12959
- Give MethodParamsProviderEvent the location of the call by @jirkace in https://github.com/vimeo/psalm/pull/13325
- fix(scanner): suppress MissingClassConstType on the class by @jirkace in https://github.com/vimeo/psalm/pull/12932
- Accept non-ASCII variable names in @param, @param-out, @global and @property by @jirkace in https://github.com/vimeo/psalm/pull/12700
- fix(callmap): mysqli get_warnings may return false by @jirkace in https://github.com/vimeo/psalm/pull/12826
- fix(alter): keep the data flow of a read fixed as possibly undefined by @jirkace in https://github.com/vimeo/psalm/pull/13386
- Infer a literal string for trim() of a literal string by @jirkace in https://github.com/vimeo/psalm/pull/12602
- Keep $this as it was after following a method called in a constructor by @jirkace in https://github.com/vimeo/psalm/pull/13332
- fix(by-ref): accept a constant or call result for a parameter only the stub takes by reference #7505 by @jirkace in https://github.com/vimeo/psalm/pull/13263
- fix(stubs): type array_find, array_find_key, array_first and array_last by @jirkace in https://github.com/vimeo/psalm/pull/12642
- Treat a while loop whose condition holds for the literal start as always entered by @jirkace in https://github.com/vimeo/psalm/pull/12622
- fix(throws): report uncaught exceptions thrown inside foreach, for and while loops by @jirkace in https://github.com/vimeo/psalm/pull/13229
- fix(loop): the value of a foreach iteration is not the one the last iteration ended with by @jirkace in https://github.com/vimeo/psalm/pull/13437
- Don't crash psalter on properties declared together by @jirkace in https://github.com/vimeo/psalm/pull/12599
- Honour an inline @psalm-suppress UnusedVariable by @jirkace in https://github.com/vimeo/psalm/pull/12611
- Don't report a nullable array key from an ignored nullable return by @jirkace in https://github.com/vimeo/psalm/pull/12605
- Keep a concatenation with mixed no emptier than its other operand by @jirkace in https://github.com/vimeo/psalm/pull/12591
- Accept in by @jirkace in https://github.com/vimeo/psalm/pull/12600
- Apply a conditional @psalm-taint-escape to calls of instance methods by @jirkace in https://github.com/vimeo/psalm/pull/12621
- Accept interfaces in universalObjectCrates and cover their implementations by @jirkace in https://github.com/vimeo/psalm/pull/12612
- fix(ternary): narrow by the branch that finishes when the other one throws or exits by @jirkace in https://github.com/vimeo/psalm/pull/12639
- fix(properties): report docblock type issues of a typed property at the docblock by @jirkace in https://github.com/vimeo/psalm/pull/12636
- Scan the classes of the global variables of the config by @jirkace in https://github.com/vimeo/psalm/pull/12631
- Give the closure of a
- Report
- 7.1.02026-11-08 · 2026-11-08 02:28 UTC
查看更新说明
What's Changed
Features
- fix(parser): allow a trailing comma in array and list shapes by @jirkace in https://github.com/vimeo/psalm/pull/13228
Fixes
- :sparkles: [#11509] Fix regression about iterables, list and conditional types by @andrew-demb in https://github.com/vimeo/psalm/pull/11558
- test(psalter): pin a constructor inherited from another file with MissingThrowsDocblock by @jirkace in https://github.com/vimeo/psalm/pull/13346
- feat(stubs): substr of a non-empty-string from its start is non-empty by @jirkace in https://github.com/vimeo/psalm/pull/12921
- fix(properties): the self of a trait property signature is the using class by @jirkace in https://github.com/vimeo/psalm/pull/12919
- fix(isset): a variable not set by the isset branch stays possibly undefined after the if by @jirkace in https://github.com/vimeo/psalm/pull/13046
- fix(unused): a call on the left of ?? is used by the coalesce by @jirkace in https://github.com/vimeo/psalm/pull/13231
- fix(call): give the callback of usort() and its siblings the element type of the array by @jirkace in https://github.com/vimeo/psalm/pull/13347
- fix(call): keep the narrowed type of an unchanged argument in strict_types by @jirkace in https://github.com/vimeo/psalm/pull/13341
- fix(parser): accept a name after the = or ... of a callable param by @jirkace in https://github.com/vimeo/psalm/pull/13226
- fix(types): a literal string id does not use the C escapes \a and \b by @jirkace in https://github.com/vimeo/psalm/pull/13209
- fix(loop): report break/continue levels exceeding the enclosing structures by @jirkace in https://github.com/vimeo/psalm/pull/13210
- fix(foreach): drop the invalid-iteration null of an Iterator's current() and key() by @jirkace in https://github.com/vimeo/psalm/pull/13218
- fix(interface): report an undefined interface in an interface's extends list by @jirkace in https://github.com/vimeo/psalm/pull/13212
- fix(inheritance): compare constructors that override an abstract constructor by @jirkace in https://github.com/vimeo/psalm/pull/13211
- fix(docblock): report the class issues of a @var type at the docblock by @jirkace in https://github.com/vimeo/psalm/pull/13182
- fix(return): report a void|never docblock return type that can only return implicitly by @jirkace in https://github.com/vimeo/psalm/pull/13169
- fix(strings): keep the literals of a union in an interpolated string by @jirkace in https://github.com/vimeo/psalm/pull/13130
- fix(try): a catch whose every path leaves does not make the variables of the try possibly undefined by @jirkace in https://github.com/vimeo/psalm/pull/13183
- fix(unused): report the unused result of a pure static method call by @jirkace in https://github.com/vimeo/psalm/pull/13197
- fix(properties): a redeclared protected property is accessible from the classes of its first declaration by @jirkace in https://github.com/vimeo/psalm/pull/13203
- fix(docblock): a tag of a single-line docblock has no trailing blank by @jirkace in https://github.com/vimeo/psalm/pull/13193
- Handle missing parents when checking inherited constants by @orklah in https://github.com/vimeo/psalm/pull/13414
- fix(params): honour @psalm-suppress InvalidParamDefault by @jirkace in https://github.com/vimeo/psalm/pull/13172
- fix(callable): resolve [object, 'method'] callables to inherited and trait methods by @jirkace in https://github.com/vimeo/psalm/pull/13214
- fix(docblock): allow a trailing comma in a generic type by @jirkace in https://github.com/vimeo/psalm/pull/13208
- fix(stubs): FFI::memcmp prefers references but also accepts values by @jirkace in https://github.com/vimeo/psalm/pull/13173
- [6.x] Fix crash when a closure unsets a by-reference captured variable (backport) by @alies-dev in https://github.com/vimeo/psalm/pull/12058
- [6.x] Fix type variables bounded by another type variable (backport) by @alies-
- 6.20.102026-11-07 · 2026-11-07 17:26 UTC
查看更新说明
What's Changed
Fixes
- :sparkles: [#11509] Fix regression about iterables, list and conditional types by @andrew-demb in https://github.com/vimeo/psalm/pull/11558
Internal changes
- Fix 6.x CI: retry transient stub build failures, update array_first test by @danog in https://github.com/vimeo/psalm/pull/13407
Full Changelog: https://github.com/vimeo/psalm/compare/6.20.9...6.20.10
- 7.0.52026-11-07 · 2026-11-07 00:41 UTC
查看更新说明
What's Changed
Fixes
- feat(taint): json_encode() without JSON_PRETTY_PRINT removes the header taint by @jirkace in https://github.com/vimeo/psalm/pull/12799
- Feature/callmap signature return types by @orklah in https://github.com/vimeo/psalm/pull/13167
- Exclude extension polyfills from PHP-versioned callmaps by @orklah in https://github.com/vimeo/psalm/pull/13345
- fix(methods): static return of an inherited method is the class that inherits it by @jirkace in https://github.com/vimeo/psalm/pull/12994
- fix(callmap): PDO::sqliteCreateFunction() takes flags since PHP 7.1.4 by @jirkace in https://github.com/vimeo/psalm/pull/12865
- fix(callmap): define() accepts any value since PHP 8.1 by @jirkace in https://github.com/vimeo/psalm/pull/12992
Internal changes
- Add zstd cache compression with a dictionary for the consolidated cache by @alies-dev in https://github.com/vimeo/psalm/pull/13309
Full Changelog: https://github.com/vimeo/psalm/compare/7.0.4...7.0.5
- 7.0.42026-11-06 · 2026-11-06 00:42 UTC
查看更新说明
What's Changed
Fixes
- fix(baseline): merge duplicated files and issue types when reading a baseline by @jirkace in https://github.com/vimeo/psalm/pull/13098
- fix(visibility): drop the empty context from the inaccessible method message by @jirkace in https://github.com/vimeo/psalm/pull/13094
- fix(psalter): replace the whole union return type by @jirkace in https://github.com/vimeo/psalm/pull/13116
- fix(arithmetic): don't fold a shift by a negative number or zero to a negative power by @jirkace in https://github.com/vimeo/psalm/pull/13103
- fix(int-range): an int range without bounds is int by @jirkace in https://github.com/vimeo/psalm/pull/13091
- fix(types): a negated instanceof narrows the bound of a template param by @jirkace in https://github.com/vimeo/psalm/pull/12906
- fix(types): keep named objects and other shapes next to an object with properties by @jirkace in https://github.com/vimeo/psalm/pull/13101
- Perf: skip recording code use edges that nothing reads (2–32% less memory when unused code detection is off) by @alies-dev in https://github.com/vimeo/psalm/pull/13250
- Evaluate the keys of array items passed by reference once by @alies-dev in https://github.com/vimeo/psalm/pull/13297
- Fix: constants defined in Psalm's process turn into mixed on warm runs by @alies-dev in https://github.com/vimeo/psalm/pull/13302
- fix(int-range): a negative int to the power of 0 is 1 by @jirkace in https://github.com/vimeo/psalm/pull/13186
- fix(stubs): SplDoublyLinkedList::offsetSet accepts null to append by @jirkace in https://github.com/vimeo/psalm/pull/13207
- fix(parser): as, of and is are keys of a shape where a colon follows by @jirkace in https://github.com/vimeo/psalm/pull/13075
- fix(types): $_COOKIE can have int keys by @jirkace in https://github.com/vimeo/psalm/pull/12868
- fix(config): count referencedFunction issue handler suppressions by @jirkace in https://github.com/vimeo/psalm/pull/12854
- fix(scanner): an and/or condition of unknown parts defines both branches by @jirkace in https://github.com/vimeo/psalm/pull/12814
- Keep the type of the elements array_splice() returns by @jirkace in https://github.com/vimeo/psalm/pull/12615
- fix(param-out): do not check the @param-out of a method without a body by @jirkace in https://github.com/vimeo/psalm/pull/12681
- Ask whether the package of an unknown plugin class is installed by @danog in https://github.com/vimeo/psalm/pull/13326
Internal changes
- Perf: speed up warm runs and the consolidated cache with one file per cache entry by @alies-dev in https://github.com/vimeo/psalm/pull/13249
Full Changelog: https://github.com/vimeo/psalm/compare/7.0.3...7.0.4
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
Psalm is a static analysis tool for finding errors in PHP applications.
Join the official Psalm news channel and the Psalm community on Telegram and Discord!
Installation
To get started, check out the installation guide.
Live Demo
You can play around with Psalm on its website.
Documentation
Documentation is available on Psalm’s website, generated from the docs folder.
Support Psalm development
You can support Psalm development by requesting a support contract from Daniil Gentili, the only active maintainer of Psalm.
Support contracts can cover full integration of Psalm into existing codebases, support for Psalm issues and development of additional Psalm features.
See here » for info, pricing and contact information.
Interested in contributing?
Have a look at CONTRIBUTING.md.
Who made this
Built by Matt Brown (@muglug).
Maintained by Daniil Gentili (@danog) and Alies Lapatsin (@alies-dev).
Former maintainers: Orklah (@orklah) and Bruce Weirdan (@weirdan).
The engineering team at Vimeo have provided a lot encouragement, especially @nbeliard, @erunion and @nickyr.