Correzione dell’errore "La classe non può essere salvata nella directory del codice/generato"

In questo articolo viene descritto come risolvere il problema in cui il modo in cui sono state specificate le dipendenze impedisce la generazione automatica immediata delle classi e il messaggio di errore Classe non può essere salvato nella directory generata/codice.

Descrizione description

Ambiente

Adobe Commerce su infrastruttura cloud 2.2.0 o versione successiva

Problema/Sintomi

Passaggi da riprodurre:

  1. Nell’ambiente locale, scrivi una classe personalizzata con una dipendenza dalla classe generata automaticamente.
  2. Esegui lo scenario in cui viene attivata la classe personalizzata e verificane il corretto funzionamento.
  3. Apporta le modifiche all'ambiente di integrazione. Questo attiverebbe il processo di distribuzione. Implementazione completata.
  4. Nell’ambiente di integrazione, esegui lo scenario in cui viene attivata la classe personalizzata.

Risultato previsto:

Tutto funziona correttamente, nello stesso modo in cui funziona nell’ambiente locale.

Risultato effettivo

Errore con il messaggio di errore che indica che la classe non può essere salvata nella directory generata/code.

Causa principale

La causa del problema è che la classe sulla quale si ha la dipendenza non viene generata durante la distribuzione e non può essere generata in un secondo momento quando la classe viene attivata, perché la directory generated/code non è disponibile per la scrittura dopo il completamento della distribuzione.

Questo può accadere per due motivi principali:

Caso 1: La classe con dipendenze da classi generate automaticamente si trova nel punto di ingresso, ad esempio index.php, che non viene analizzato per individuare le dipendenze durante la distribuzione.
Caso 2: La dipendenza dalla classe generata automaticamente viene specificata direttamente (rispetto all'utilizzo consigliato di un costruttore per dichiarare la dipendenza).

Risoluzione resolution

Una soluzione comune per entrambi i casi sarebbe la creazione di una fabbrica reale invece della classe generata automaticamente. Oppure c'è una soluzione particolare per ogni caso.

Soluzione specifica per il caso 1

Spostare il codice di classe dal punto di ingresso a un modulo separato e quindi utilizzarlo nel punto di ingresso.

Esempio:

Codice originale, ad esempio, 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

Devi effettuare le seguenti operazioni:

  1. Sposta la definizione della classe in 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. Modificare il punto di ingresso my_api/index.php in modo che sia simile al seguente:

    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
    

Soluzione specifica per il caso 2

Sposta la dichiarazione di dipendenza nel costruttore.

Esempio:

Dichiarazione di classe originale:

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

È necessario modificare il costruttore come segue:

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

Lettura correlata

Generazione del codice nella documentazione per gli sviluppatori.

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