<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>PHPStan on Leanku 的博客</title><link>https://www.leanku.com/tags/phpstan/</link><description>Recent content in PHPStan on Leanku 的博客</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Fri, 09 Aug 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://www.leanku.com/tags/phpstan/index.xml" rel="self" type="application/rss+xml"/><item><title>composer analyse —— 静态分析工具 PHPStan 完全指南</title><link>https://www.leanku.com/post/php/composer-analyse-phpstan/</link><pubDate>Fri, 09 Aug 2024 00:00:00 +0000</pubDate><guid>https://www.leanku.com/post/php/composer-analyse-phpstan/</guid><description>&lt;h1 id="composer-analyse--静态分析工具-phpstan-完全指南"&gt;composer analyse —— 静态分析工具 PHPStan 完全指南&lt;/h1&gt;&#10;&lt;h2 id="一phpstan-是什么"&gt;一、PHPStan 是什么？&lt;/h2&gt;&#10;&lt;p&gt;PHPStan 是 PHP 生态中&lt;strong&gt;最广泛采用的静态分析工具&lt;/strong&gt;，它可以在不运行代码的情况下，通过分析代码的语法、类型和调用链，提前发现潜在的逻辑错误和 Bug。是现代 PHP 项目的标配工具之一。&lt;/p&gt;&#10;&lt;h3 id="核心价值"&gt;核心价值&lt;/h3&gt;&#10;&lt;p&gt;PHPStan 的核心价值在于&lt;strong&gt;在代码运行前发现问题&lt;/strong&gt;。与单元测试不同，单元测试需要编写测试用例并实际执行代码，而静态分析则通过扫描源码即可完成检查，成本更低、覆盖更广。&lt;/p&gt;&#10;&lt;p&gt;例如，假设有以下代码：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;User::find()&lt;/code&gt; 在未找到记录时可能返回 &lt;code&gt;null&lt;/code&gt;，但方法声明只返回 &lt;code&gt;User&lt;/code&gt; 类型。PHPStan 会立即报告：&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;Method getUser() should return User but returns User|null.&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这种类型不匹配问题如果不经静态分析，可能要等到生产环境运行时才会暴露。&lt;/p&gt;&#10;&lt;h3 id="phpstan-的检查级别"&gt;PHPStan 的检查级别&lt;/h3&gt;&#10;&lt;p&gt;PHPStan 采用&lt;strong&gt;0–9 共 10 个检查级别&lt;/strong&gt;，级别越高检查越严格：&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;级别&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;检查内容&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;0&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;基础检查：未定义的类、函数、方法调用&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;1&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;未定义的变量、未知的魔术方法&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;返回值类型、参数类型（基于 PHPDoc）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;3&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;死代码检测、恒真/恒假条件&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;4&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;方法调用时的参数类型检查&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;5&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;强制类型提示（missing typehints）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;6+&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;并集类型严格检查（逐步增加严格度）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;&lt;strong&gt;渐进式采用的策略&lt;/strong&gt;：对于已有项目，建议从 level 0 或 level 1 开始，逐步提升。每次提升级别时，如果错误过多，可先生成基线文件（baseline）将现有问题暂时忽略，之后只关注新增问题。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="二真实场景配置与使用"&gt;二、真实场景配置与使用&lt;/h2&gt;&#10;&lt;h3 id="场景示例通用-php-项目的-phpstan-配置"&gt;场景示例：通用 PHP 项目的 PHPStan 配置&lt;/h3&gt;&#10;&lt;p&gt;对于非 Laravel 的 PHP 项目（如 Hyperf、Symfony、原生 PHP 应用），标准 PHPStan 配置即可满足需求。&lt;/p&gt;</description></item><item><title>composer cs-fix —— 代码风格修复工具 PHP-CS-Fixer</title><link>https://www.leanku.com/post/php/composer-cs-check-php_codesniffer/</link><pubDate>Thu, 08 Aug 2024 00:00:00 +0000</pubDate><guid>https://www.leanku.com/post/php/composer-cs-check-php_codesniffer/</guid><description>&lt;h1 id="composer-cs-check--代码风格检查与修复工具-php_codesniffer"&gt;composer cs-check —— 代码风格检查与修复工具 PHP_CodeSniffer&lt;/h1&gt;&#10;&lt;p&gt;在现代 PHP 项目开发中，代码风格的一致性是保障团队协作效率和代码可维护性的重要基石。与自动修复的 PHP-CS-Fixer 不同，PHP_CodeSniffer 作为 PHP 领域历史最悠久的代码风格工具，凭借其&lt;strong&gt;检查与修复功能分离&lt;/strong&gt;的设计和强大的可扩展性，在代码审查和 CI/CD 流程中扮演着&amp;quot;检察官&amp;quot;的角色。&lt;/p&gt;&#10;&lt;h2 id="1-什么是-php_codesniffer"&gt;1. 什么是 PHP_CodeSniffer？&lt;/h2&gt;&#10;&lt;p&gt;PHP_CodeSniffer 是一套用于检测和修复 PHP、JavaScript 和 CSS 文件编码标准违规问题的工具集。它的核心设计理念与 PHP-CS-Fixer 不同，将&lt;strong&gt;检查&lt;/strong&gt;与&lt;strong&gt;修复&lt;/strong&gt;拆分为两个独立命令，分工极其清晰：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;&lt;code&gt;phpcs&lt;/code&gt; (PHP Code Sniffer)&lt;/strong&gt;：负责扫描代码，检测违反编码标准的问题并报告错误或警告（可设置报错等级）。它本身&lt;strong&gt;不会修改任何代码&lt;/strong&gt;，只负责指出问题。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;&lt;code&gt;phpcbf&lt;/code&gt; (PHP Code Beautifier and Fixer)&lt;/strong&gt;：负责自动修正 &lt;code&gt;phpcs&lt;/code&gt; 发现的可修复问题。例如 PSR-2 规范要求每个 PHP 文件结尾需有一行空行，运行 &lt;code&gt;phpcbf&lt;/code&gt; 后就能自动补上。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;PHP_CodeSniffer 在 Packagist 上的下载量位居前列，是 PHP 领域最成熟、生态最完善的代码风格工具之一。&lt;/p&gt;&#10;&lt;h2 id="2-适用场景"&gt;2. 适用场景&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;场景&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;说明&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;代码审查（Code Review）&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;在 Pull Request 中运行 &lt;code&gt;phpcs&lt;/code&gt;，提供详细的违规报告，作为评审依据&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;CI/CD 质量门禁&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;作为持续集成流程的检查环节，风格不合格则阻止合并&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;团队规范统一&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;在遗留项目中快速建立风格基线，不直接修改代码，风险可控&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;IDE 实时检查&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;在 PhpStorm 等 IDE 中集成，编码时实时高亮风格问题&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;PHP 版本兼容性检查&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;配合 PHPCompatibility 规则集，检测代码是否兼容目标 PHP 版本&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;&lt;strong&gt;最佳实践&lt;/strong&gt;：在 CI 流程中使用 &lt;code&gt;phpcs&lt;/code&gt; 进行&lt;strong&gt;只读检查&lt;/strong&gt;，在本地开发中使用 &lt;code&gt;phpcbf&lt;/code&gt; 进行&lt;strong&gt;自动修复&lt;/strong&gt;。这种&amp;quot;检查与修复分离&amp;quot;的设计让 PHP_CodeSniffer 在自动化质量保障场景中比 PHP-CS-Fixer 更具优势。&lt;/p&gt;</description></item></channel></rss>