Correção do erro "A classe não pode ser salva no diretório gerado/código"

Este artigo descreve como corrigir o problema em que a maneira como você especificou dependências impede que as classes sejam geradas automaticamente em tempo real, e você recebe a mensagem de erro A classe não pode ser salva no diretório gerado/de código.

Descrição description

Ambiente

Adobe Commerce na infraestrutura em nuvem 2.2.0 ou posterior

Problema/Sintomas

Etapas a serem reproduzidas:

  1. No ambiente local, escreva uma classe personalizada com uma dependência na classe gerada automaticamente.
  2. Execute o cenário em que sua classe personalizada é acionada e veja se ela funciona corretamente.
  3. Confirme e envie suas alterações para o ambiente de integração. Isso acionaria o processo de implantação. Implantação bem-sucedida.
  4. No ambiente de integração, execute o cenário em que sua classe personalizada é acionada.

Resultado esperado:

Tudo funciona corretamente, da mesma forma que no seu ambiente local.

Resultado real

Falha com a mensagem de erro informando que a sua Classe não pode ser salva no diretório gerado/código.

Causa raiz

A causa do problema é que a classe na qual você tem dependência não é gerada durante a implantação e não pode ser gerada posteriormente quando a classe é acionada, pois o diretório generated/code não está disponível para gravação após a implantação ser concluída.

Há duas razões principais pelas quais isso pode acontecer:

Caso 1: A classe com dependências em classes geradas automaticamente está localizada no ponto de entrada (como index.php), que não é verificado em busca de dependências durante a implantação.
Caso 2: A dependência na classe gerada automaticamente é especificada diretamente (compare com o uso recomendado de um construtor para declarar dependência).

Resolução resolution

Uma solução comum para ambos os casos seria criar uma fábrica real em vez da classe gerada automaticamente. Ou há uma solução específica para cada caso.

Solução específica para o caso 1

Mova seu código de classe do ponto de entrada para um módulo separado e use-o no ponto de entrada.

Exemplo:

Código original em, por exemplo, 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

Você precisa executar as seguintes etapas:

  1. Mover a definição de classe para 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. Edite o ponto de entrada my_api/index.php de forma que ele tenha a seguinte aparência:

    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
    

Solução específica para o caso 2

Mova a declaração de dependência para o construtor.

Exemplo:

Declaração de classe original:

<?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...}

Você precisa alterar seu construtor da seguinte maneira:

<?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...}

Leitura relacionada

Geração de código em nossa documentação para desenvolvedores.

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