-1

我想在 Symfony 5.2.3 中使用 Nette Database 3.1.1。我的 PHP 版本是 8.0。

当我尝试在命令中创建数据库连接时,出现以下错误。

“自动加载器预期类“Nette\Database\IConventions”将在文件“/var/www/html/vendor/composer/../nette/database/src/compatibility-intf.php”中定义。找到该文件但类不在其中,类名或命名空间可能有错字。”

但是,在控制器中创建数据库连接就可以了。在命令行上执行文件时,也可以在没有 Symfony 的文件中创建数据库连接。

这是我的命令。

<?php

declare(strict_types=1);

namespace App\Command;

use Nette\Database\Connection;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

class TestCommand extends Command
{
    protected static $defaultName = 'app:test';
    protected static $defaultDescription = 'Add a short description for your command';

    protected function configure()
    {
        $this->setDescription(self::$defaultDescription);
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);

        $database = new Connection(
            'mysql:host=127.0.0.1;dbname=test',
            'test',
            'xxx'
        );

        return Command::SUCCESS;
    }
}

这是异常的痕迹。

Exception trace:
  at /var/www/html/vendor/symfony/error-handler/DebugClassLoader.php:400
 Symfony\Component\ErrorHandler\DebugClassLoader->checkClass() at /var/www/html/vendor/symfony/error-handler/DebugClassLoader.php:357
 Symfony\Component\ErrorHandler\DebugClassLoader->loadClass() at n/a:n/a
 interface_exists() at /var/www/html/vendor/nette/database/src/Database/Conventions.php:45
 include() at /var/www/html/vendor/symfony/error-handler/DebugClassLoader.php:346
 Symfony\Component\ErrorHandler\DebugClassLoader->loadClass() at n/a:n/a
 class_alias() at /var/www/html/vendor/nette/database/src/compatibility-intf.php:23
 include() at /var/www/html/vendor/symfony/error-handler/DebugClassLoader.php:346
 Symfony\Component\ErrorHandler\DebugClassLoader->loadClass() at n/a:n/a
 interface_exists() at /var/www/html/vendor/nette/database/src/Database/Driver.php:100
 include() at /var/www/html/vendor/symfony/error-handler/DebugClassLoader.php:346
 Symfony\Component\ErrorHandler\DebugClassLoader->loadClass() at /var/www/html/vendor/nette/database/src/Database/Drivers/MySqlDriver.php:18
 include() at /var/www/html/vendor/symfony/error-handler/DebugClassLoader.php:346
 Symfony\Component\ErrorHandler\DebugClassLoader->loadClass() at /var/www/html/vendor/nette/database/src/Database/Connection.php:77
 Nette\Database\Connection->connect() at /var/www/html/vendor/nette/database/src/Database/Connection.php:56
 Nette\Database\Connection->__construct() at /var/www/html/src/Command/TestCommand.php:30
 App\Command\TestCommand->execute() at /var/www/html/vendor/symfony/console/Command/Command.php:256
 Symfony\Component\Console\Command\Command->run() at /var/www/html/vendor/symfony/console/Application.php:989
 Symfony\Component\Console\Application->doRunCommand() at /var/www/html/vendor/symfony/framework-bundle/Console/Application.php:96
 Symfony\Bundle\FrameworkBundle\Console\Application->doRunCommand() at /var/www/html/vendor/symfony/console/Application.php:290
 Symfony\Component\Console\Application->doRun() at /var/www/html/vendor/symfony/framework-bundle/Console/Application.php:82
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /var/www/html/vendor/symfony/console/Application.php:166
 Symfony\Component\Console\Application->run() at /var/www/html/bin/console:43
4

1 回答 1

0

我确认了这个相当令人费解的问题。我认为这是与 PHP 的预加载和 Symfony 的交互。问题出在这里:

# compatibility-intf.php
} elseif (!interface_exists(ISupplementalDriver::class)) {
    class_alias(Driver::class, ISupplementalDriver::class);
    class_alias(Conventions::class, IConventions::class);
}

它只在为 IConventions 创建别名之前检查驱动程序接口。将其更改为:

if (!interface_exists(ISupplementalDriver::class)) {
    class_alias(Driver::class, ISupplementalDriver::class);
}
if (!interface_exists(IConventions::class)) {
    class_alias(Conventions::class, IConventions::class);
}

会让你解决问题。显然编辑供应商文件并不理想。我建议在 github 网站上打开一个问题。最近似乎有一些活动,因此它可能会很快被纳入。如果没有,那么您将不得不分叉回购并自己调整它。

于 2021-03-03T15:24:18.653 回答