koriit/phpdeps

用于查找模块间循环依赖的库

v0.1.0 2018-05-04 21:38 UTC

This package is auto-updated.

Last update: 2024-09-29 05:08:21 UTC


README

目录

Build Status

Coverage Status Scrutinizer Code Quality StyleCI SensioLabsInsight

Latest Stable Version License

关于

PHPDeps是一个简单的工具,用于检测模块中的循环依赖,无论你将什么视为模块或包。

模块是组织良好的代码单元,应被视为单一实体。通过将类和函数分组到模块中,我们可以在更高层次的抽象级别上进行推理。

安装

PHPDeps通过composer提供

composer require --dev koriit/phpdeps

请注意,PHPDeps在开发过程中使用。它不是您应用程序的一部分,因此使用--dev

为什么关心?

这是一个通用的编程问题。如果您对这个问题不熟悉,或者只是需要复习,以下是一些快速参考

  1. 为什么循环依赖很糟糕

  2. 什么是循环依赖,为什么它很糟糕?

  3. 循环依赖

  4. 无环依赖原则

  5. 面向对象设计原则(无环依赖原则部分;最后,大多数作者都会参考这篇文献)

方法

PHPDeps通过读取PHP文件的use部分来检测模块使用情况。这意味着PHPDeps需要命名空间存在

PHPDeps假设属于单个模块的所有类和函数在其完全限定名称中具有相同的命名空间前缀。

例如,如果我们告诉PHPDeps,SomeModule的命名空间为ACME\Lib\Modules\SomeModule,并且PHPDeps分析属于OtherModule的以下文件

<?php
namespace ACME\Lib\Modules\OtherModule;

use ACME\Lib\Modules\SomeModule\Exceptions\ObjectNotFound;
// ...

然后PHPDeps注意到OtherModule依赖于SomeModule

一旦分析完所有模块,PHPDeps创建一个依赖图,并查找其中的任何循环。

基本用法

如果您已配置并设置好,只需执行

vendor/bin/phpdeps

如果您的配置文件不是命名为phpdeps.xml,则可以将其作为--config选项传递

vendor/bin/phpdeps --config=myPHPDepsConfig.xml

建议将phpdeps调用添加到您的composer.json中的脚本部分

  "scripts": {
    "dependencies": "phpdeps"
  }

您还可以在测试的同时运行它

  "scripts": {
    "test": ["phpunit", "phpdeps"]
  }

示例

让我们考虑PHPDeps自身的简化结构

/src/PHPDeps
|-- ExtCodes.php
|-- PHPDepsApplication.php
|-- /Commands/
|-- /Config/
|-- /Modules/
|-- /Helpers/

首先,您需要准备一个配置文件,允许PHPDeps找到您的模块

phpdeps.xml
<?xml version="1.0" encoding="UTF-8"?>
<PHPDeps xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="vendor/koriit/phpdeps/phpdeps.xsd">

    <Modules> <!--(1)-->
        <Module>
            <Name>PHPDepsApplication</Name> <!--(2)-->
            <Namespace>Koriit\PHPDeps\PHPDepsApplication</Namespace> <!--(3)-->
            <Path>./src/PHPDeps/PHPDepsApplication.php</Path> <!--(4)-->
        </Module>
    </Modules>

    <Detectors> <!--(5)-->
        <ModuleDetector>
            <Namespace>Koriit\PHPDeps</Namespace> <!--(6)-->
            <Path>./src/PHPDeps</Path> <!--(7)-->
        </ModuleDetector>
    </Detectors>

</PHPDeps>
  1. 第一种选项是直接定义您的模块。

  2. 每个模块需要一个名称,但目前这仅用于显示目的。

  3. 每个模块还需要一个命名空间前缀,这用于检查是否有其他模块依赖于它。如果是文件,则需要该模块的完全限定名称。

  4. 模块路径允许PHPDeps找到并分析您的模块,这可以是文件路径或目录路径。

  5. 第二种选项是定义模块检测器,目前PHPDeps仅支持基于目录的模块检测。

  6. 命名空间前缀,找到的模块的目录名附加到此以创建实际的模块命名空间。

  7. 搜索模块的目录。

一旦准备好配置,您可以执行

vendor/bin/phpdeps

如果一切正常,您将得到一个漂亮的OK消息

[OK] There are no circular dependencies in your modules!

如果出现问题,您将得到

[WARNING] There are circular dependencies in your modules!

In total there are 4 dependency cycles in your modules.

1. Commands -> Modules -> Commands
----------------------------------

2. Commands -> Config -> Modules -> Commands
--------------------------------------------

3. Commands -> Helpers -> Modules -> Commands
---------------------------------------------

4. Commands -> Helpers -> Config -> Modules -> Commands
-------------------------------------------------------

请注意,此示例是通过向Modules模块中的Commands模块添加一个依赖来生成的。

目前PHPDeps不提供任何额外的帮助来解决循环依赖问题。

退出代码

配置

配置是一个简单的XML文件。提供的XSD允许代码补全和易于验证。目前,配置仅使用简单的格式,只包含XML标签,没有属性

  • <PHPDeps> - 配置根元素。

    • <Modules> - 所有模块定义的分组标签。

      • <Module> - 定义并描述单个模块。

        • <Name> - 模块名称,用于显示目的。

        • <Namespace> - 命名空间前缀,用于检查是否有其他模块依赖于它。如果模块是文件,则这需要是模块的完全限定名称。

        • <Path> - 模块路径允许PHPDeps找到并分析您的模块,这可以是文件路径或目录路径。

    • <Detectors> - 所有检测定义的分组标签。

      • <ModuleDetector> - 定义并描述单个基本模块检测器。

        • <Namespace> - 命名空间前缀,找到的模块的目录名附加到此处以创建实际的模块命名空间。

        • <Path> - 搜索模块的目录。

配置示例

phpdeps.xml
<?xml version="1.0" encoding="UTF-8"?>
<PHPDeps xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="vendor/koriit/phpdeps/phpdeps.xsd">

    <Modules>
        <Module>
            <Name>PHPDepsApplication</Name>
            <Namespace>Koriit\PHPDeps\PHPDepsApplication</Namespace>
            <Path>./src/PHPDeps/PHPDepsApplication.php</Path>
        </Module>
    </Modules>

    <Detectors>
        <ModuleDetector>
            <Namespace>Koriit\PHPDeps</Namespace>
            <Path>./src/PHPDeps</Path>
        </ModuleDetector>
    </Detectors>

</PHPDeps>

命令和选项

请参考内置的帮助命令。