Psalm是一个静态分析工具,深入程序,尽可能多地找到与类型相关的bug
混合类型警告
Intelligent logic checks
属性初始化检查
Taint analysis
Language Server
Automatic fixes
Automatic refactoring
安装
shell
composer global require --dev vimeo/psalm
# 当使用这个方式安装时,如果psalm的依赖和项目依赖有冲突,可使用phar安装
composer global require --dev psalm/phar
注意:
linux 上,需要将全局composer的可执行目录加入环境变量,目录路径一般是/tmp/composer/vendor/bin
环境变量配置windows 上,只需在环境变量path中加上composer路径,目录路径一般是
%APPDATA%\Composer\vendor\bin
初始化
shell
./vendor/bin/psalm --init
psalm扫描你的项目,评估适合项目的错误级别,并生成psalm.xml文件用于后续的扫描配置
执行
shell
./vendor/bin/psalm
#或者扫描某个或某些文件
./vendor/bin/psalm file1.php [file2.php...]
shell
./vendor/bin/psalm --show-info=true
参数解释:
--show-info 显示非异常的分析结果
shell
#针对特定问题给出psalm的解决方案,可参考其结果进行代码修复
./vendor/bin/psalm --alter --issues=MissingReturnType --dry-run
参数解释:
--issues all 显示全部问题解决方案;其他问题type,多个间以逗号分隔,如 MissingReturnType,InvalidArgument
插件
查看可用插件列表
shell
composer search -t psalm-plugin '.'
安装
shell
composer global require --dev <plugin-vendor/plugin-package>
启用
shell
vendor/bin/psalm-plugin enable plugin-vendor/plugin-package
禁用
shell
vendor/bin/psalm-plugin disable plugin-vendor/plugin-package
显示已安装列表
shell
vendor/bin/psalm-plugin show
配置
以下是我的配置,大家可以根据情况选择配置
yaml
<?xml version="1.0"?>
<psalm
errorLevel="4"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
findUnusedBaselineEntry="true"
findUnusedCode="true"
autoloader="psalm_autoloader.php"
allowStringToStandInForClass="true"
>
<!-- 添加错误忽略配置 -->
<issueHandlers>
<DocblockTypeContradiction>
<errorLevel type="suppress">
<directory name="app"/>
<!--<file name="path/to/file_with_unused_methods.php"/>-->
</errorLevel>
</DocblockTypeContradiction>
<NonInvariantDocblockPropertyType>
<errorLevel type="suppress">
<directory name="app"/>
</errorLevel>
</NonInvariantDocblockPropertyType>
<PossiblyUndefinedArrayOffset>
<errorLevel type="suppress">
<directory name="app"/>
</errorLevel>
</PossiblyUndefinedArrayOffset>
<PossiblyInvalidOperand>
<errorLevel type="suppress">
<directory name="app"/>
</errorLevel>
</PossiblyInvalidOperand>
<PossiblyUndefinedVariable>
<errorLevel type="suppress">
<directory name="app"/>
</errorLevel>
</PossiblyUndefinedVariable>
<RiskyTruthyFalsyComparison>
<errorLevel type="suppress">
<directory name="app"/>
</errorLevel>
</RiskyTruthyFalsyComparison>
<PossiblyInvalidMethodCall>
<errorLevel type="suppress">
<directory name="app/model"/>
</errorLevel>
</PossiblyInvalidMethodCall>
<MissingReturnType>
<errorLevel type="suppress">
<directory name="app/model"/>
</errorLevel>
</MissingReturnType>
<PossiblyNullOperand>
<errorLevel type="suppress">
<directory name="app/model"/>
</errorLevel>
</PossiblyNullOperand>
<PossiblyNullArgument>
<errorLevel type="suppress">
<directory name="app/model"/>
</errorLevel>
</PossiblyNullArgument>
<PropertyNotSetInConstructor>
<errorLevel type="suppress">
<directory name="app"/>
</errorLevel>
</PropertyNotSetInConstructor>
<UnusedClass>
<errorLevel type="suppress">
<directory name="app"/>
</errorLevel>
</UnusedClass>
<PossiblyUnusedMethod>
<errorLevel type="suppress">
<directory name="app"/>
</errorLevel>
</PossiblyUnusedMethod>
<UndefinedConstant>
<errorLevel type="suppress">
<directory name="app"/>
<directory name="config"/>
</errorLevel>
</UndefinedConstant>
<UnusedConstructor>
<errorLevel type="suppress">
<file name="app/redis"/>
</errorLevel>
</UnusedConstructor>
<UnusedMethod>
<errorLevel type="suppress">
<file name="app/common"/>
</errorLevel>
</UnusedMethod>
<UnusedFunctionCall>
<errorLevel type="suppress">
<file name="app/common.php"/>
</errorLevel>
</UnusedFunctionCall>
<PossiblyUnusedProperty>
<errorLevel type="suppress">
<file name="app/BaseController.php"/>
</errorLevel>
</PossiblyUnusedProperty>
<InvalidArrayOffset>
<errorLevel type="suppress">
<file name="app/common.php"/>
</errorLevel>
</InvalidArrayOffset>
<InvalidArgument>
<errorLevel type="suppress">
<file name="config/database.php"/>
</errorLevel>
</InvalidArgument>
</issueHandlers>
<!-- 配置需要扫描的范围,以及需要忽略的目录和文件 -->
<projectFiles>
<directory name="app" />
<directory name="config" />
<ignoreFiles>
<directory name="vendor" />
<directory name="test" />
<file name="app/command/Swagger.php" />
</ignoreFiles>
</projectFiles>
</psalm>
文档解释:
issueHandlers 中是扫描问题的类型,其中directory 是需要忽略问题的目录,file是需要忽略问题的文件
自动化构建(Jenkins)中使用
参考文章 jenkins插件之Warnings 项目配置 一章中的psalm章节