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
- Nell’ambiente locale, scrivi una classe personalizzata con una dipendenza dalla classe generata automaticamente.
- Esegui lo scenario in cui viene attivata la classe personalizzata e verificane il corretto funzionamento.
- Apporta le modifiche all'ambiente di integrazione. Questo attiverebbe il processo di distribuzione. Implementazione completata.
- 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:
-
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... }
-
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
- Generazione del codice nella documentazione per gli sviluppatori.