Åtgärda felet"Klassen kan inte sparas i katalogen generated/code"
I den här artikeln beskrivs hur du åtgärdar problemet där det sätt som du angav beroenden förhindrar att klasser genereras automatiskt i farten, och du får felmeddelandet Klassen kan inte sparas i den genererade kodkatalogen.
Beskrivning description
Miljö
Adobe Commerce i molninfrastruktur 2.2.0 eller senare
Problem/symtom
Steg att återskapa:
- I den lokala miljön skriver du en anpassad klass med ett beroende på den automatiskt genererade klassen.
- Kör scenariot där din anpassade klass utlöses och se hur den fungerar.
- Genomför och överför ändringarna till integreringsmiljön. Detta skulle utlösa distributionsprocessen. Distributionen har slutförts.
- Kör det scenario där din anpassade klass utlöses i integreringsmiljön.
Förväntat resultat:
Allt fungerar korrekt, på samma sätt som i din lokala miljö.
Faktiskt resultat
Fel: Felmeddelandet anger att din klass inte kan sparas i den genererade katalogen/kodkatalogen.
Rotorsak
Orsaken till problemet är att den klass som du är beroende av inte genereras under distributionen och inte kan genereras senare när klassen aktiveras, eftersom katalogen generated/code inte är tillgänglig för skrivning när distributionen har slutförts.
Det finns två huvudorsaker till detta:
Fall 1: Klassen med beroenden för automatiskt genererade klasser finns i startpunkten (till exempel index.php), som inte genomsöks efter beroenden under distributionen.
Fall 2: Beroendet av den automatiskt genererade klassen anges direkt (jämfört med den rekommenderade användningen av en konstruktor för att deklarera beroende).
Upplösning resolution
En vanlig lösning för båda fallen är att skapa en riktig fabrik i stället för den automatiskt genererade klassen. Eller så finns det en speciell lösning för varje fall.
Specifik lösning för fall 1
Flytta klasskoden från startpunkten till en separat modul och använd den sedan i startpunkten.
Exempel:
Ursprunglig kod i, till exempel, 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
Du måste göra följande:
-
Flytta klassdefinitionen till
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... } -
Redigera startpunkten
my_api/index.phpså att den ser ut så här: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
Specifik lösning för fall 2
Flytta beroendedeklarationen till konstruktorn.
Exempel:
Ursprunglig klassdeklaration:
<?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...}
Du måste ändra konstruktorn så här:
<?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...}
Relaterad läsning
Kodgenerering i utvecklardokumentationen.