首页  >  问答  >  正文

Composer 自动加载找不到该类

我有一个具有以下结构的项目:

- src
  + Guitar.php
  + Type.php
  + ToString.php
- tests
  + GuitarTest.php
composer.json

这就是我在composer.json中定义psr-4自动加载的方式:

"autoload": {
    "psr-4": {
        "Shop\Guitar\": "src/"
    }
}

这是我的 Guitar.php:

<?php

namespace Shop\Guitar;

require_once __DIR__ . '/../vendor/autoload.php';

use Shop\Guitar\Type;

class Guitar
{
    public function __construct(public readonly string $serialNumber, public readonly Type $type)
    {
    }
}

这是我的 ToString.php:

<?php

namespace Shop\Guitar;

require_once __DIR__ . '/../vendor/autoload.php';

interface ToString
{
    public function toString(): string;
}

这是我的 Type.php:

<?php

namespace Shop\Guitar;

require_once __DIR__ . '/../vendor/autoload.php';

enum Type implements ToString
{
    case ACOUSTIC;
    case ELECTRIC;

    public function toString(): string
    {
        return match($this)
        {
            self::ACOUSTIC => 'Acoustic',
            self::ELECTRIC => 'Electric',
        };
    }
}

这是我的 GuitarTest.php:

<?php

require_once __DIR__ . '/../vendor/autoload.php';

use PHPUnit\Framework\TestCase;
use Shop\Guitar\Guitar;
use Shop\Guitar\Type;

final class InventoryTest extends TestCase
{
    public function testGuitarConstructor(): void
    {
        $guitar = new Guitar('foo', Type::ELECTRIC);
    }
}

但是当我运行测试时,出现以下错误:

Error: Class "Shop\Guitar\Guitar" not found

问题是什么?如何解决?

P粉403804844P粉403804844180 天前359

全部回复(1)我来回复

  • P粉764836448

    P粉7648364482024-03-27 12:15:40

    这只是一个关于 PSR-4 配置中的 Composer 自动加载器的问题。

    • 您的composer.json 配置看起来合法。
    • require_once 调用则不会。这是一个自动加载器,类文件一定不需要自动加载器。

    如果有疑问,请测试您的自动加载器配置。

    后续步骤:

    1. 删除那些 require_once 调用,它们只会分散您的注意力并妨碍故障排除。自动加载配置要么有效,要么无效。如果您将包含点分布在不同的文件上,则需要进行更多维护工作,但完全没有必要这样做。

    2. 重新组织您的测试模块以引入自动加载器配置测试,因为您遇到了问题:

      1. 将内容从 tests 移至 tests/unit 中,为单元测试提供专用目录。

      2. 创建 tests/php 子文件夹并在其中创建 autoloading.php 文件。该文件夹用于 PHP 测试,即直接使用 PHP 执行它们(例如 phptests/php/autoloading.php)。文件内容:

        参考文献:

    3. 运行自动加载器配置测试,检​​查文件是否可以加载

      $ php tests/php/autoloading.php
      

    (它不能打印任何内容,但可能会打印任何内容。重要的是它会运行,而不是文件未找到或类似类型的错误。

    如果您能够以这种方式执行 PHP 文件,请将其绑定到 Composer 配置中。这样您就可以测试自动加载器配置。

    将新脚本添加到您的 composer.json 配置中:

    {
        "script": {
            "post-autoload-dump": [
                "@php -dzend.assertions=1 -dassert.exception=0 tests/php/autoloading.php"
            ]
        }
    }
    

    参考文献:

    并测试它:

    $ composer run-script post-autoload-dump
    > @php -dzend.assertions=1 -dassert.exception=0 tests/php/autoloading.php
    PHP Warning:  assert(): [ ...

    (它不能给出输出,这里我添加了一些警告以显示它的外观)

    这将运行新的自动加载配置测试,并在警告模式下启用断言。也就是说,如果任何 ***_exists() 函数返回 false,您就会看到错误。这意味着无法加载接口/枚举/类。

    您可以通过将 -dassert.exception=0 更改为 -dassert.exception=1 (0 -> <代码>1)。然后测试将以非零代码退出(状态 255 因为未捕获的异常)。

    这就是你想要的,将 -dassert.exception=0 更改为 -dassert.exception=1 并再次保存 composer.json .

    然后您可以使用任何转储自动加载器的 Composer 命令来测试您的自动加载器:

    • 作曲家转储自动加载
    • 作曲家安装
    • 作曲家更新

    测试愉快。


    适当的测试,也许同时检查 phpunit 是否仍在运行:

    $ composer exec phpunit -- tests/unit
    PHPUnit ...

    再次进行测试,当您找到罪魁祸首并且一切都恢复正常时,您可以使用单个编写器脚本运行所有测试。

    Common 是一个带有单词 test 的脚本:

    {
        "script": {
            "post-autoload-dump": [
                "@php -dzend.assertions=1 -dassert.exception=0 tests/php/autoloading.php"
            ],
            "test": [
              "@composer dump-autoload",
              "@composer exec phpunit"
            ]
        }
    }
    

    并且您不需要一直编写 composer run-script test,只需 composer test 就足够了:

    $ composer test
    Generating autoload files
    Generated autoload files
    > @php -dzend.assertions=1 -dassert.exception=1 tests/php/autoloading.php
    PHPUnit ...
    Time: 28 ms, Memory: 4.00MB
    
    No tests executed!
    

    (在此示例输出中,我尚未配置 phpunit 测试,但您明白了)


    那么这是什么样的测试呢?好吧,我称之为配置测试,它只是一个快速检查,您可以在其中验证一些 PHP 内容。不要添加许多这样的测试并保持较小的测试计划。您可以使用它来解决配置项目时遇到的问题。保留长达一年,如果您一直没有错误,那么您可以考虑将其删除。

    但是,该示例显示了如何使某些检查更靠近配置位置并将它们绑定在一起。如果存在非零退出状态,Composer 将使整个过程失败。

    此外,您可以为每个编写器脚本添加描述,以便显示一条消息:

    {
        "scripts-descriptions": {
            "test": "Runs all tests."
        }
    }
    
    $ composer list
    ...
      test                 Runs all tests.
    ...

    (请参阅:自定义描述 - Composer 脚本文档

    回复
    0
  • 取消回复