Erro "A classe não pode ser salva no diretório de código"
- Tópicos:
- Configuração
Criado para:
- Desenvolvedor
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 gerada/código".
Produtos e versões afetados
- Adobe Commerce na infraestrutura em nuvem 2.2.0 ou posterior
Problema
Etapas a serem reproduzidas
- No ambiente local, escreva uma classe personalizada com uma dependência na classe gerada automaticamente.
- Execute o cenário em que sua classe personalizada é acionada e veja se ela funciona corretamente.
- Confirme e envie suas alterações para o ambiente de integração. Isso acionaria o processo de implantação. Implantação bem-sucedida.
- 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 classe não pode ser salva no diretório generated/code
.
Causa
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 da classe gerada automaticamente é especificada diretamente (compare com o uso recomendado do construtor para declarar dependência).
Solução
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
:
<?php
use 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:
-
Mover a definição de classe para
app/code/YourVendor/YourModule
:<?php namespace YourVendor\YourModule; use YourVendor\YourModule\Model\GeneratedFactory; class YourClass { private $generatedFactory; public function __construct(GeneratedFactory $generatedFactory) { $this->generatedFactory = $generatedFactory; } // Some code here... }
-
Edite o ponto de entrada
my_api/index.php
de forma que ele tenha a seguinte aparência:<?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:
<?php
namespace 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:
<?php
namespace 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.