composer cs-check —— 代码风格检查与修复工具 PHP_CodeSniffer

在现代 PHP 项目开发中,代码风格的一致性是保障团队协作效率和代码可维护性的重要基石。与自动修复的 PHP-CS-Fixer 不同,PHP_CodeSniffer 作为 PHP 领域历史最悠久的代码风格工具,凭借其检查与修复功能分离的设计和强大的可扩展性,在代码审查和 CI/CD 流程中扮演着"检察官"的角色。

1. 什么是 PHP_CodeSniffer?

PHP_CodeSniffer 是一套用于检测和修复 PHP、JavaScript 和 CSS 文件编码标准违规问题的工具集。它的核心设计理念与 PHP-CS-Fixer 不同,将检查与修复拆分为两个独立命令,分工极其清晰:

  • phpcs (PHP Code Sniffer):负责扫描代码,检测违反编码标准的问题并报告错误或警告(可设置报错等级)。它本身不会修改任何代码,只负责指出问题。
  • phpcbf (PHP Code Beautifier and Fixer):负责自动修正 phpcs 发现的可修复问题。例如 PSR-2 规范要求每个 PHP 文件结尾需有一行空行,运行 phpcbf 后就能自动补上。

PHP_CodeSniffer 在 Packagist 上的下载量位居前列,是 PHP 领域最成熟、生态最完善的代码风格工具之一。

2. 适用场景

场景说明
代码审查(Code Review)在 Pull Request 中运行 phpcs,提供详细的违规报告,作为评审依据
CI/CD 质量门禁作为持续集成流程的检查环节,风格不合格则阻止合并
团队规范统一在遗留项目中快速建立风格基线,不直接修改代码,风险可控
IDE 实时检查在 PhpStorm 等 IDE 中集成,编码时实时高亮风格问题
PHP 版本兼容性检查配合 PHPCompatibility 规则集,检测代码是否兼容目标 PHP 版本

最佳实践:在 CI 流程中使用 phpcs 进行只读检查,在本地开发中使用 phpcbf 进行自动修复。这种"检查与修复分离"的设计让 PHP_CodeSniffer 在自动化质量保障场景中比 PHP-CS-Fixer 更具优势。

3. 安装与配置

3.1 通过 Composer 安装(推荐)

在项目的 composer.json 中添加依赖:

composer require --dev squizlabs/php_codesniffer

安装完成后,可以通过 vendor/bin 目录调用:

./vendor/bin/phpcs -h
./vendor/bin/phpcbf -h

3.2 其他安装方式

Phar 方式(适用于 CI 环境):

curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar
php phpcs.phar -h

curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcbf.phar
php phpcbf.phar -h

全局安装(使用 Composer):

composer global require "squizlabs/php_codesniffer=*"

确保 Composer 的 bin 目录在系统 PATH 中(默认 ~/.composer/vendor/bin/)。

3.3 设置默认编码标准

为了避免每次手动指定标准,可以设置全局默认值:

# 设置默认标准为 PSR-2(或 PSR-12)
phpcs --config-set default_standard PSR12
phpcbf --config-set default_standard PSR12

⚠️ 注意:PSR-2 已被 PSR-12 取代,推荐使用 PSR12 作为基础标准。

3.4 在 composer.json 中定义脚本

{
    "scripts": {
        "cs-check": "./vendor/bin/phpcs",
        "cs-fix": "./vendor/bin/phpcbf"
    }
}

4. 使用方法

4.1 基础命令

# 检查单个文件
./vendor/bin/phpcs test.php

# 检查整个目录
./vendor/bin/phpcs src/

# 指定编码标准
./vendor/bin/phpcs --standard=PSR12 src/

# 显示错误对应的 sniff 代码(用于配置)
./vendor/bin/phpcs -s src/

4.2 执行自动修复

# 修复单个文件
./vendor/bin/phpcbf test.php

# 修复整个目录
./vendor/bin/phpcbf src/

# 指定编码标准
./vendor/bin/phpcbf --standard=PSR12 src/

📌 phpcbf 默认只输出摘要报告,包含修复的文件数和修复的错误数。如需要详细输出,可加 -v 参数。

4.3 输出示例

phpcs 执行后的典型输出:

FILE: /project/src/User.php
----------------------------------------------------------------------
FOUND 5 ERRORS AND 2 WARNINGS AFFECTING 8 LINES
----------------------------------------------------------------------
  12 | ERROR   | [x] Opening brace should be on a new line
  15 | WARNING | [ ] Line exceeds 120 characters
  28 | ERROR   | [x] Expected 1 space after comma, 0 found
  34 | ERROR   | [ ] Missing docblock for method foo()
  42 | ERROR   | [x] Expected 1 space before closing parenthesis
----------------------------------------------------------------------
PHPCBF CAN FIX THE 3 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------

其中,带 [x] 标记的问题表示 phpcbf 可以自动修复。

5. 配置文件深度解析

5.1 创建配置文件

在项目根目录创建 phpcs.xml(或 phpcs.xml.dist),PHP_CodeSniffer 会自动检测。

5.2 基础配置模板

<?xml version="1.0"?>
<ruleset name="My Project Coding Standard">
    <!-- 描述 -->
    <description>基于 PSR-12 的项目编码规范</description>

    <!-- 指定要检查的文件和目录 -->
    <file>src/</file>
    <file>tests/</file>

    <!-- 排除目录 -->
    <exclude-pattern>src/Legacy/*</exclude-pattern>
    <exclude-pattern>tests/Fixtures/*</exclude-pattern>

    <!-- 使用 PSR-12 作为基础标准 -->
    <rule ref="PSR12"/>

    <!-- 排除基础标准中的某些规则 -->
    <rule ref="PSR12">
        <exclude name="Generic.WhiteSpace.DisallowTabIndent"/>
        <exclude name="Generic.ControlStructures.InlineControlStructure"/>
    </rule>

    <!-- 包含额外的第三方 Sniff(需单独安装) -->
    <rule ref="SlevomatCodingStandard.TypeHints.PropertyTypeHint"/>
    <rule ref="SlevomatCodingStandard.TypeHints.ReturnTypeHint"/>
</ruleset>

5.3 高级配置示例

自定义错误消息和严重程度:

<!-- 修改 TODO 注释的错误消息和严重程度 -->
<rule ref="Generic.Commenting.Todo.TaskFound">
    <message>请复审此 TODO 注释:%s</message>
    <severity>3</severity>
</rule>

<!-- 将错误降级为警告 -->
<rule ref="Generic.Commenting.Todo.CommentFound">
    <type>warning</type>
</rule>

调整 Sniff 参数:

<!-- 调整行长度限制:90 字符警告,100 字符错误 -->
<rule ref="Generic.Files.LineLength">
    <properties>
        <property name="lineLimit" value="90"/>
        <property name="absoluteLineLimit" value="100"/>
    </properties>
</rule>

<!-- 指定换行符为 Windows 风格 -->
<rule ref="Generic.Files.LineEndings">
    <properties>
        <property name="eolChar" value="\r\n"/>
    </properties>
</rule>

引用外部自定义 Sniff:

如果项目中有自定义 Sniff 实现(需实现 PHP_CodeSniffer\Sniffs\Sniff 接口),可以这样引用:

<rule ref="/path/to/_dev/IncludeUsingDirSniff.php"/>

或通过 sniffPaths 配置扫描路径:

<config name="sniffPaths" value="/var/www/project/_dev"/>

6. 第三方规则集

PHP_CodeSniffer 强大的生态体现在丰富的第三方规则集上。以下是两个流行的扩展:

6.1 Slevomat Coding Standard

这是 PHP_CodeSniffer 最流行的扩展包,提供了大量现代化的类型检查和代码质量规则。

composer require --dev slevomat/coding-standard

在配置中引用:

<rule ref="SlevomatCodingStandard.TypeHints.ParameterTypeHint"/>
<rule ref="SlevomatCodingStandard.TypeHints.PropertyTypeHint"/>
<rule ref="SlevomatCodingStandard.TypeHints.ReturnTypeHint"/>

<!-- 强制启用 mixed 类型提示(默认未启用) -->
<rule ref="SlevomatCodingStandard.TypeHints.ParameterTypeHint">
    <properties>
        <property name="enableMixedTypeHint" value="true"/>
    </properties>
</rule>

6.2 arxeiss/coding-standards 规则集

这是一个预配置的规则集包,基于 PSR-2 + PSR-12 并附加额外规则,同时支持空格缩进和 Tab 缩进。

composer require --dev arxeiss/coding-standards

使用时,在 phpcs.xml 中引用:

<rule ref="./vendor/arxeiss/coding-standards/Rules/phpcs-spaces.xml"/>

6.3 PHPCompatibility(PHP 版本兼容性检查)

这是 PHP_CodeSniffer 最著名的非风格类规则集,用于检测代码是否兼容特定 PHP 版本:

composer require --dev phpcompatibility/php-compatibility

配置示例:

<rule ref="PHPCompatibility"/>
<config name="testVersion" value="7.4-8.2"/>

7. IDE 集成(PhpStorm)

PhpStorm 提供了对 PHP_CodeSniffer 的原生集成,支持实时检查和批量运行。

7.1 通过 Composer 自动集成

当通过 Composer 安装 squizlabs/php_codesniffer 后,PhpStorm 会自动检测 vendor/bin 中的可执行文件并注册 IDE。

7.2 手动配置路径

如需要手动配置,进入 Settings → PHP → Quality Tools → PHP_CodeSniffer:

  • 配置 phpcs 和 phpcbf 可执行文件路径
  • 选择 PHP 解释器(支持 Docker 远程解释器)
  • 设置运行选项

7.3 启用检查

配置完成后,可在 Settings → Editor → Inspections 中搜索 phpcs 启用检查。

开启后:

  • 实时检查:编辑器会高亮显示风格问题,与 PhpStorm 内置检查样式相同
  • 批量检查:可通过 Code → Inspect Code 运行,问题显示在 Problems 工具窗口,带 phpcs 前缀以区分

7.4 配置 External Tools 运行 phpcbf

PhpStorm 未提供 phpcbf 的直接按钮,但可通过 External Tools 配置:

  1. Settings → Tools → External Tools 添加
  2. 设置 phpcbf 路径和参数(如 $FileDir$)

配置后在代码文件上右键 → External Tools → phpcbf 即可修复当前文件。

8. CI/CD 集成(GitHub Actions)

name: Code Style Check

on:
  pull_request:
  push:
    branches: [main, develop]

jobs:
  cs-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'
          tools: composer

      - name: Install dependencies
        run: composer install --no-progress

      - name: Run CodeSniffer Check
        run: composer cs-check

9. 与 PHP-CS-Fixer 的对比

特性PHP_CodeSnifferPHP-CS-Fixer
核心哲学检查与报告优先修复优先
命令分工phpcs + phpcbf 两个独立命令一个命令通过不同参数实现两种功能
历史地位元老级,始于2006年后来者,但社区活跃度高
规则扩展Sniff 生态成熟,有 PHPCompatibility 等专用规则集Fixer 规则丰富,现代化语法支持好
擅长领域代码审查、CI检查、版本兼容性检测日常代码格式化和现代化

10. 常见问题与故障排查

问题解决方案
phpcs 未找到规则集检查 --standard 参数是否正确,或用 phpcs -i 查看已安装的规则集
phpcbf 未修复任何问题确认问题是否被标记为 [x],只有带标记的问题才能自动修复
CI 中报错但本地正常检查 CI 环境的 PHP 版本与本地是否一致
自定义 Sniff 无法加载确认 sniffPaths 配置正确,且 Sniff 类实现了 Sniff 接口并正确注册了 Token 类型
IDE 未检测到 Composer 安装的 PHP_CodeSniffer重置配置:进入 Settings → PHP → Quality Tools → PHP_CodeSniffer,清空路径字段,然后更新 Composer 依赖,IDE 会重新自动检测

PHP_CodeSniffer 可以成为团队代码质量保障体系中"风格一致性"与"版本兼容性"两道防线的核心工具,与 PHP-CS-Fixer 形成互补,共同维护代码的整洁与健康。