Psalm 起效关键在于 psalm.xml 与 composer.json autoload 配置严格对齐;必须执行 psalm --init(推荐选 medium),手动修正 <directory> 路径,确保与 PSR-4 映射一致,并在 CI 中先运行 composer dump-autoload -o。

Psalm 不是装上就能用的工具,composer require --dev vimeo/psalm 只是第一步;真正起作用的是 psalm --init 生成的 psalm.xml 是否与 Composer 的自动加载配置对齐——90% 的 “Class not found” 报错,根源都在这里。
psalm --init 必须立刻执行,且选 medium 规模
装完不跑 psalm --init,psalm.xml 就不会生成,后续所有配置都无效。它会交互式询问项目规模:
-
small:跳过深层调用链分析,容易漏掉InvalidReturnType -
medium:默认启用合理规则集,适合新项目起步(推荐) -
large:开一堆严格规则(如MixedAssignment全开),新手常被卡在第一轮扫描
它还会自动猜源码目录(比如扫到 src/ 就写 <directory name="src"/>),但这个“猜”不读 composer.json,所以大概率要手动改。
psalm.xml 的 <directory> 必须和 composer.json 的 autoload 完全一致
Psalm 不自己解析类路径,而是复用 Composer 的 autoloader 映射。如果 composer.json 是这样:
<code>"autoload": {
"psr-4": {
"App\": "app/"
}
}</code>那 psalm.xml 就必须写:
<code><projectFiles> <directory name="app"/> </projectFiles></code>
否则会出现:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
ERROR: UndefinedClass - src/Service/UserService.php:12:21 - Class AppModelUser was not found(其实是路径没配对) -
INFO: UnusedClass却不报错——因为 Psalm 根本没把tests/当作项目文件,除非你显式加<directory name="tests"/>
全局函数文件(如 src/helpers.php)也得在 composer.json 的 "files" 字段声明,否则 Psalm 看不见。
CI 中 psalm 失效?先检查 composer dump-autoload 和 --no-dev
CI 环境没有本地缓存,vendor/autoload.php 的映射必须是最新生成的:
- 运行
composer dump-autoload -o再跑psalm,否则 Psalm 会 fallback 到慢速文件扫描,甚至超时 -
composer install --no-dev会跳过vimeo/psalm,导致vendor/bin/psalm消失——CI 必须分两阶段:先带--dev跑 Psalm,通过后再用--no-dev构建生产包 - 别用
autoloader="vendor/autoload.php"覆盖默认行为,Psalm 本来就会读这个文件,加了反而可能破坏路径解析
快速验证 autoload 是否生效:在 CI 脚本里加一句 php -r "var_dump(class_exists('YourMainClass'));",返回 false 就说明 autoload 链路断了。
“Unable to resolve class Xyz” 怎么定位?从 class_exists 开始
这不是 Psalm 的 bug,是 autoloader 层的问题:
- 先跑
php -r "var_dump(class_exists('Xyz'));"—— 如果返回false,问题出在 Composer,不是 Psalm - 检查
composer.json的autoload段:命名空间末尾少反斜杠("App"写成"App")、路径实际是lib/却写了src/ - 第三方扩展(如
ext-redis)没有 PHP 类文件 → 此时才该用<stubs>,且必须手写完整 stub 文件并显式声明在psalm.xml中
最容易被忽略的一点:新增 PSR-4 映射或改过 composer.json 后,composer dump-autoload 必须手动再跑一次——否则 Composer 根本不认新类,Psalm 自然也 resolve 不到。

















