php静态分析

phpdoc https://docs.phpdoc.org/latest/packages/phpDocumentor-AST.html



phpstan https://github.com/phpstan/phpstan



php-parser https://github.com/nikic/PHP-Parser



https://psalm.dev/
https://github.com/vimeo/psalm



https://github.com/phan/phan



https://github.com/nikic/php-ast



https://github.com/kalessil/phpinspectionsea

phpstan
它目前校验什么?
有关类中涉及的,对象实例, 错误 / 异常捕获,类型约束以及其他语言结构的存在性。 PHP 照旧不会检查这些, 但是会展现其中未被使用的代码。
被调用的方法和函数的存在性和可访问性。同样也会检查他们的参数个数。
方法是否返回了它声明的返回值类型。
被访问成员变量的存在性和可见性。它也可指出是否将一个其他的类型的值赋给了既定类型的成员变量。
sprintf/printf 函数基于格式化字符串所应接收的参数个数。
分支和循环范围中的变量的存在性。
无用的形式指定。例如 (string) ‘foo’ ,以及不同类型变量间的严格比较 (=== 和 !==),因为他们的结果总为 false。
这个清单的内容随着每次发布都在递增。但成就 PHPStan 也不会只仰赖此一技之微。



即便当前正在使用静态类型,开发者也可以合法的使用 PHP 的动态语法特性,例如 get, set 和 __call 这些魔术方法。它们可以在运行时去定义新属性和方法。通常,静态分析都会爆出属性和方法未定义,但是有一种机制可以告诉引擎如何创建新的属性和方法。



它得益于对允许用户扩展的原生 PHP 反射的自定义抽象。更多细节可查看 README 中类反射扩展章节。



某些方法返回的类型取决于它的参数。它可以取决于你传递给它的类名,也可能返回与传递的对象相同的类的对象。这就是 动态返回类型扩展 的用途。



压轴语: 如果你想自己出一个 PHPStan 的新的检查项, 你可以自力更生。可以提出基于特定框架的规则,例如检查 DQL 查询中引用的实体和字段是否存在,或者你选择的 MVC 框架中生成的链接是否和现存的控制器有关。



选择规范级别
我使用过其他工具,并将之集成进现有的代码库中,这种体验真是往事不堪回首。他们爆出成千上万的错误让你没法使用。



取而代之,我回顾如何集成 PHPStan 到刚进入开发阶段的代码库中。 首个版本的功能不是很强大,这时并未发现多少错误。但从集成的角度来看,它还是非常不错的 — 有空时,我就为它增加新规则,我修复了它在版本库中找到的错误,并将新代码合并到主分支。我们会使用新版本几周用来发现其找到的错误,并不断重复这件事。这种逐级增加的规范性的做法在实践中看来大有裨益,所以我使用 PHPStan 的现有功能来模拟它。



默认情况下,PHPStan 只检查它确定的代码 — 常量,实例化,调用 $ this 的方法,静态调用的方法,函数和各种语言结构中的现有类。 通过增加级别(从默认值 0 到当前值 4),您还可以增加它对代码所做的假设数量以及它检查的规则数量。



如果内建级别无法满足你的要求,你同样也可以自定义规则。



少写单元测试!(披沙拣金)
可能这个建议你闻所未闻。即便是非常细碎的代码,开发者也不得不编写单元测试,因为这方面犯错的几率都是均等的,例如简单的拼写错误或者忘记将结果赋值给变量。为那些经常出现在控制器或者门脸中的转发代码编写单元测试是很不划算的事。



单元测试也有其成本。它们同样也是代码,难逃编写和维护的窠臼。最理想的做法就是在持续集成服务器上,每次更改时都运行 PHPStan,从而在无需单元测试的情况下防止此类错误的产生。实现 100%的代码覆盖率真的很难,并且非常昂贵,但你可以静态分析 100%的代码。



至于单元测试的重点应当集中在静态分析代码难以察觉的,容易出错的地方。包括:复杂的数据过滤,循环,条件判断,乘除法包含舍入的计算等
https://learnku.com/laravel/t/19011



目前,PHPStanV0.10.2要求系统环境的PHP版本不低于7.1。用Composer全局安装:
$ composer global require phpstan/phpstan
复制代码使用
PHPStan静态分析的使用方法十分简单:
$ phpstan analyse [-c|–configuration CONFIGURATION]
[-l|–level LEVEL] [–no-progress] [–debug]
[-a|–autoload-file AUTOLOAD-FILE] [–errorFormat ERRORFORMAT]
[–memory-limit MEMORY-LIMIT] [–] []...
复制代码
configuration:运行配置文件的路径;
level:严格级别,0-7,越大越严格;
no-progress:不显示进度;
debug:debug模式;
autoload-file:自动加载文件的路径;
errorFormat:错误格式;
memory-limit:内存限制;
paths:待分析的文件路径



https://zhuanlan.zhihu.com/p/127142794
https://www.fzb.me/2017-7-18-static-analysis-in-php.html



https://learnku.com/articles/38855



https://blog.csdn.net/s2603898260/article/details/105632270
https://blog.csdn.net/roger_ranger/article/details/78768802



https://wjqwsp.github.io/2018/07/07/linux%E5%8F%AF%E6%89%A7%E8%A1%8C%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84%E5%8F%8A%E9%93%BE%E6%8E%A5%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90/



http://staff.ustc.edu.cn/~chengli7/courses/compiler18/notes/Lecture12_intermediate_code_generation1.pdf



Category php