Errore "Impossibile salvare la classe nella directory del codice"

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 viene visualizzato il messaggio di errore "Impossibile salvare la classe nella directory generato/code".

Prodotti e versioni interessati

  • Adobe Commerce su infrastruttura cloud 2.2.0 o versione successiva

Problema

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 generated/code.

Causa

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 su classi generate automaticamente si trova nel punto di ingresso (ad esempio index.php ), che non viene analizzato per individuare dipendenze durante la distribuzione.
  • Caso 2: la dipendenza dalla classe generata automaticamente viene specificata direttamente (rispetto all'utilizzo consigliato del costruttore per dichiarare la dipendenza).

Soluzione

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:

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

Devi effettuare le seguenti operazioni:

  1. Sposta la definizione della classe in app/code/YourVendor/YourModule:

    code language-php
       <?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-php
      <?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:

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

È necessario modificare il costruttore come segue:

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

Lettura correlata

recommendation-more-help
8bd06ef0-b3d5-4137-b74e-d7b00485808a