【问题标题】:CodeSniffer sniff for generating dependency graphs for PHP code?CodeSniffer 嗅探为 PHP 代码生成依赖关系图?
【发布时间】:2012-10-31 12:31:59
【问题描述】:

目标: 我有兴趣在 PHP 程序中生成类依赖项的 DOT Format 描述。

想法: 编写一个可以在 PHP 源代码中检测(并发出 DOT 记录)以下模式的 CodeSniffer“嗅探”应该不难:

class SomeClassName extends BasicClassName {  // SomeClassName refers to BasicClassName
...
    new OtherClassName();            // SomeClassName refers to OtherClassName
    ThisClassName::some_method();    // SomeClassName refers to ThisClassName
    ThatClassName::$some_member;     // SomeClassName refers to ThatClassName
    RandomClassName::some_constant;  // SomeClassName refers to RandomClassName
...
}

但我还没有找到任何已发布的嗅探来发出此信息(以及任何其他表明我可能错过的“真实”类依赖关系的模式)。

注意: 我特别关心 PHP 的 include() 和 require() 语句 (whose behavior I'm not convinced is even well-defined)。出于这个问题的目的,我们假设所有 PHP 类解析都是通过 autoloading 处理的,并且我们希望仅使用静态代码分析来构建类依赖关系图。

编辑: 不幸的是,我认为没有通用的方法来处理以下问题:

class ThatClassName {
...
    function generateClassName() {
        // something too complicated to analyze statically...
    }

    function foo() {
        $name = $this->generateClassName();
        $instance = new $name; // ThatClassName refers to ... what?
        ...
    }
...
}

但是,当然可以通过显示 ThatClassName 与 generateClassName() 方法的依赖关系来在依赖关系图中表示这种情况 - 可能用括号显示以使方法名称易于与类名称区分开来。建立一个约定可能不是一个坏主意,即任何动态生成类名的方法都必须包含一个annotation(在相关注释中),它指示可能生成的每个类名——这些“记录的动态依赖关系”然后可以自动包含在依赖关系图中。

【问题讨论】:

  • DOT 格式的链接失效,请修复。
  • 谢谢,@BobKruithof - 链接已修复。

标签: php static-analysis codesniffer


【解决方案1】:

这并不是 PHP_CodeSniffer 真正设计的目的;特别是因为嗅探不应该输出数据或写入文件。但是,肯定没有什么能阻止你在嗅探中这样做。毕竟只是 PHP 代码,不需要报告任何错误或警告。

我没有遇到任何像你描述的那样做任何事情的嗅探,所以我认为你必须写一个新的。

如果您想创建新的嗅探,我建议您从抽象范围嗅探开始。这允许您在 T_CLASS 令牌中查找 T_NEW 和 T_DOUBLE_COLON 令牌。 Here is an example.

或者,如果您还想查看全局函数和其他类之外的代码,您可以在常规嗅探中查找 T_NEW 和 T_DOUBLE_COLON 标记

如果您不确定如何开始,或者您只是想获得一些帮助来编写嗅探,请联系我,我可以帮助您编写此内容。我只需要知道你想要找到的每个案例的输出,或者我可以只使用一些基本的东西。如果你想帮忙,我的邮箱是:gsherwood at squiz dot net

【讨论】:

  • 您好 Greg,我承认您是许多“标准”CodeSniffer 嗅探的作者,非常感谢您提供的帮助(并感谢您的参考)。当然,我承认 Codesniffer 旨在检查是否符合编码风格标准 - 但是,CodeSniffer 能够使用句法智能解析整个代码库,使其成为执行各种静态分析杂务的理想平台。例如,我修改了另一个“通用”嗅探(你的?)用于查找重复的类名)以生成文件->类映射以用于自动加载器。
  • 我会按照你的建议写一个嗅探。如果我遇到麻烦,我会利用你的提议来提供帮助,当我得到一些工作时,我会建议将它添加到 CodeSniffer 发行版中(因为我相信有一天其他人会发现它有用)。
  • 听起来不错,彼得。我还维护 PHP_CodeSniffer 本身,所以如果您在标记化方面遇到任何问题,或者核心代码妨碍您,请联系并让我知道,我会看看是否可以进行任何更改以帮助您。虽然它不是 PHPCS 的设计目的,但我真的很想看看它是如何运行的,并且希望它在工作后能够被回馈。
  • 关于这是一个较老的问题,您是否提出过解决方案。我希望做一些非常相似的事情,并且希望不必重新发明轮子。
【解决方案2】:

我为此编写了一个工具:PhpDependencyAnalysis。

这是基于命名空间的面向对象 PHP 项目 (>= 5.3.3) 的可扩展静态代码分析。它在可定制的级别上创建依赖关系图,例如在包级别或类级别。因此,它通常可以用于声明依赖关系,但它也可以用于根据关注点分离、德米特法则和非循环依赖原则执行分层架构中层之间的违规检测。 您还可以将输出格式更改为 DOT。

只需检查PhpDependencyAnalysis on GitHub

【讨论】:

  • 感谢您的链接!这看起来很有趣,并且可能非常有用。在您的(非常好的)调用图文档中,您编写了“调用可以是方法参数、方法返回值或实例创建”。您的工具是否足够聪明,可以通过工厂方法跟踪对象实例的创建,还是只能通过“new”识别创建?
猜你喜欢
  • 2019-08-01
  • 2021-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多