修复了“Class cannot be saved in the generated/code directory”错误

本文介绍如何修复以下问题:指定依赖项的方式阻止即时自动生成类,并且您收到​ 类无法保存在生成的/代码目录 ​错误消息中。

描述 description

环境

云基础架构2.2.0或更高版本上的Adobe Commerce

问题/症状

重现问题的步骤:

  1. 在本地环境中,编写依赖于自动生成类的自定义类。
  2. 运行触发自定义类的方案,并查看其是否正常运行。
  3. 提交更改并将其推送到集成环境。 这将触发部署过程。 部署成功。
  4. 在集成环境中,运行触发自定义类的方案。

预期结果:

一切正常,就像在本地环境中一样。

实际结果

失败,错误消息指出您的​ 类无法保存在生成的/代码目录 ​中。

根本原因

问题的原因是,具有依赖关系的类在部署期间未生成,并且无法在触发该类时稍后即时生成,因为在部署完成后generated/code目录无法写入。

发生这种情况有两个主要原因:

用例1: 对自动生成类具有依赖关系的类位于入口点(如index.php)中,在部署期间不会扫描该入口点中的依赖关系。
用例2:直接指定了对自动生成类的依赖关系(与建议使用的构造函数声明依赖关系进行比较)。

解决方法 resolution

这两种情况的常见解决方案之一是创建一个真正的工厂,而不是自动生成类。 或者每个案例都有特定的解决方案。

案例1特定解决方案

将类代码从入口点移动到单独的模块,然后在入口点中使用它。

示例:

中的原始代码,例如index2.php

<?phpuse YourVendor\SomeModule\Model\GeneratedFactory;
require realpath(__DIR__) . '/../app/bootstrap.php';$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER);
class SomeClass{    private $generatedFactory;
    public function __construct(GeneratedFactory $generatedFactory)    {        $this->generatedFactory = $generatedFactory;    }
// Some code here...}
$someObject = $bootstrap->getObjectManager()->create(SomeClass::class);
// There is some code that uses $someObject

您需要执行以下步骤:

  1. 将类定义移动到app/code/YourVendor/YourModule

    code language-none
    <?php        namespace YourVendor\YourModule;        use YourVendor\YourModule\Model\GeneratedFactory;        class YourClass        {            private $generatedFactory;
            public function __construct(GeneratedFactory $generatedFactory)            {                $this->generatedFactory = $generatedFactory;            }        // Some code here...        }
    
  2. 编辑入口点my_api/index.php,使其类似于以下内容:

    code language-none
    <?php      use YourVendor\YourModule\YourClass;          require realpath(__DIR__) . '/../app/bootstrap.php';          $bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER);          $someObject = $bootstrap->getObjectManager()->create(YourClass::class);      // Some code using $someObject
    

案例2特定解决方案

将依赖关系声明移到构造函数。

示例:

原始类声明:

<?phpnamespace YourVendor\YourModule;
use YourVendor\SomeModule\Model\GeneratedFactory;use Magento\Framework\App\ObjectManager;
class YourClass{    private $generatedFactory;    private $someParam;
    public function __construct($someParam)    {        $this--->someParam = $someParam;        $this->generatedFactory = ObjectManager::getInstance()->get(GeneratedFactory::class);    }
    // Some code here...}

您需要更改其构造函数,如下所示:

<?phpnamespace YourVendor\YourModule;
use YourVendor\YourModule\Model\GeneratedFactory;use Magento\Framework\App\ObjectManager;
class YourClass{    private $generatedFactory;    private $someParam;
    public function __construct($someParam, GeneratedFactory $generatedFactory = null)    {        $this->someParam = $someParam;        $this->generatedFactory = $generatedFactory ?: ObjectManager::getInstance()->get(GeneratedFactory::class);    }
    // Some code here...}

相关阅读

在我们的开发人员文档中代码生成

recommendation-more-help
3d58f420-19b5-47a0-a122-5c9dab55ec7f