php质量工具系列之paslm

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章节

相关推荐
秦禹辰22 分钟前
宝塔面板安装MySQL数据库并通过内网穿透工具实现公网远程访问
开发语言·后端·golang
黄焖鸡能干四碗28 分钟前
智慧教育,智慧校园,智慧安防学校建设解决方案(PPT+WORD)
java·大数据·开发语言·数据库·人工智能
一只乔哇噻1 小时前
java后端工程师进修ing(研一版 || day41)
java·开发语言·学习·算法
lichong9511 小时前
【混合开发】vue+Android、iPhone、鸿蒙、win、macOS、Linux之video 的各种状态和生命周期调用说明
android·vue.js·macos
钮钴禄·爱因斯晨1 小时前
深入剖析LLM:从原理到应用与挑战
开发语言·人工智能
app出海创收老李1 小时前
海外独立创收日记(1)-我是如何从0到1在Google Play获得睡后被动收入的?
android·程序员
lang9998881 小时前
kodi在Android4.0.4安装播放歌曲显示歌词
android·kodi·歌词插件
六点半8881 小时前
【C++】C++11 篇二
开发语言·c++
DDDDDDDRDDR1 小时前
C++容器:list
开发语言·c++·stl
Elnaij2 小时前
从C++开始的编程生活(7)——取地址运算符重载、类型转换、static成员和友元
开发语言·c++