sirbrillig/phpcs-import-detection

一套用于查找未使用或未导入符号的phpcs嗅探器。

安装次数: 599,458

依赖者: 21

建议者: 0

安全: 0

星级: 31

关注者: 2

分支: 11

开放问题: 10

类型:phpcodesniffer-standard

v1.3.3 2022-10-30 19:04 UTC

README

一套用于查找未使用或未导入符号的phpcs嗅探器。

这添加了一个嗅探器,如果符号(函数、常量、类)被使用但没有直接定义、显式导入,也没有导入其命名空间,则会显示警告。

警告

PHP 8改变了use语句的标记方式,导致这个错误,基本上破坏了这个嗅探器。这个嗅探器的性能也相当差。我目前的工作中没有时间继续重构这个嗅探器,并且我建议至少在问题得到解决之前不要使用它。如果有人想改进这个嗅探器,请随意提交PR!

当代码移动时,如果相对或全局上下文中使用的类被移动到不同的命名空间,可能会出现问题。在这种情况下,最好使用类的完全限定命名空间,或者显式使用use(在这种情况下,它们可以通过像这样的检查器检测到)。这些警告有助于在重构代码时避免错误。

它还可以检测到未使用的导入。

例如

namespace Vehicles;
use Registry;
use function Vehicles\startCar;
use Chocolate; // this will be a warning because `Chocolate` is never used
class Car {
  public function drive() {
    startCar(); // this is fine because `startCar` is imported
    Registry\registerCar($this); // this is fine because `Registry` is imported
    \DrivingTracker\registerDrive($this); // this is fine because it's fully-qualified
    goFaster(); // this will be a warning because `goFaster` was not imported
  }
}

注意:这个嗅探器是一个轻量级语法检查器,提供对当前文件的扫描,它不知道其他文件可能已经定义了什么。因此,即使它们在同一个命名空间中,它也会警告你关于隐式导入的符号。从同一个命名空间导入某物是安全的,甚至可以改善可读性,但如果你希望扫描多个文件,我建议使用像psalmphpstan这样的静态分析工具。

安装

要在一个使用composer设置的项目中使用这些规则,我们建议使用phpcodesniffer-composer-installer库,该库会在你运行phpcs时自动使用当前项目中所有使用composer类型phpcodesniffer-standard安装的标准。

composer require --dev sirbrillig/phpcs-import-detection dealerdirect/phpcodesniffer-composer-installer

配置

在项目中安装嗅探器标准时,你编辑一个包含ruleset标签内rule标签的phpcs.xml文件。该标签的ref属性应指定一个标准、类别、嗅探器或错误代码以启用。也可以使用这些标签禁用或修改某些规则。官方注释文件解释了如何做这个。

<?xml version="1.0"?>
<ruleset name="MyStandard">
 <description>My library.</description>
 <rule ref="ImportDetection"/>
</ruleset>

嗅探器代码

这个嗅探器报告了两个嗅探器代码。两者都是警告。

  • ImportDetection.Imports.RequireImports.Symbol:一个符号被使用但没有导入
  • ImportDetection.Imports.RequireImports.Import:一个符号被导入但没有使用

在任意文件中,您可以使用phpcs注释来禁用这些嗅探器。例如,如果您有一个全局类MyGlobalClass,您不希望导入,您可以这样做:

<?php

$instance = new MyGlobalClass(); // phpcs:ignore ImportDetection.Imports.RequireImports.Symbol -- this class is global
$instance->doSomething();

对于整个文件,您可以像这样忽略一个嗅探器:

<?php
// phpcs:disable ImportDetection.Imports.RequireImports.Symbol

$instance = new MyGlobalClass();
$instance->doSomething();

对于整个项目,您可以使用phpcs.xml文件来禁用这些嗅探器或修改它们的优先级。例如,要禁用未使用导入的检查,您可以使用如下配置:

<?xml version="1.0"?>
<ruleset name="MyStandard">
 <description>My library.</description>
 <rule ref="ImportDetection"/>
 <rule ref="ImportDetection.Imports.RequireImports.Import">
   <severity>0</severity>
 </rule>
</ruleset>

忽略符号模式

通常可能存在一些全局符号,您想要使用而不导入或使用完全限定路径。

(请记住,函数调用解析首先搜索当前命名空间,然后是全局命名空间,但常量和类解析仅搜索当前命名空间!您仍然需要导入诸如 Exception 或使用完全限定的 \Exception 等内容。)

您可以使用 ignoreUnimportedSymbols 配置选项来忽略某些模式。它是一个正则表达式。以下是一些常见 WordPress 符号示例:

<?xml version="1.0"?>
<ruleset name="MyStandard">
 <description>My library.</description>
 <rule ref="ImportDetection"/>
 <rule ref="ImportDetection.Imports.RequireImports">
   <properties>
    <property name="ignoreUnimportedSymbols" value="/^(wp_parse_args|OBJECT\S*|ARRAY_\S+|is_wp_error|__|esc_html__|get_blog_\S+)$/"/>
  </properties>
 </rule>
</ruleset>

尽管名称如此,您也可以使用 ignoreUnimportedSymbols 模式来忽略特定的未使用导入。

忽略全局命名空间中的全局符号

如果一个文件位于全局命名空间中,那么有时可能不需要导入也是全局的函数。如果您想忽略全局命名空间中的全局符号使用,可以启用 ignoreGlobalsWhenInGlobalScope 选项,如下所示:

<?xml version="1.0"?>
<ruleset name="MyStandard">
 <description>My library.</description>
 <rule ref="ImportDetection"/>
 <rule ref="ImportDetection.Imports.RequireImports">
   <properties>
    <property name="ignoreGlobalsWhenInGlobalScope" value="true"/>
  </properties>
 </rule>
</ruleset>

忽略 WordPress 模式

一个常见的用例是忽略所有全局可用的 WordPress 符号。与其自己尝试想出一个模式来忽略它们,不如设置配置选项 ignoreWordPressSymbols,这将忽略它所知道的大部分内容。例如:

<?xml version="1.0"?>
<ruleset name="MyStandard">
 <description>My library.</description>
 <rule ref="ImportDetection"/>
 <rule ref="ImportDetection.Imports.RequireImports">
   <properties>
    <property name="ignoreWordPressSymbols" value="true"/>
  </properties>
 </rule>
</ruleset>

用法

大多数编辑器都提供了 phpcs 插件,但您也可以手动运行 phpcs。要在项目中运行 phpcs 对文件进行检查,只需使用以下命令行即可(-s 导致显示嗅探代码,这对于了解错误非常重要):

vendor/bin/phpcs -s src/MyProject/MyClass.php

另请参阅