Felet "Klassen kan inte sparas i kodkatalogen"
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 katalogen/kodkatalogen".
Berörda produkter och versioner
- Adobe Commerce i molninfrastruktur 2.2.0 eller senare
Problem
Steg som ska återskapas
- 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 aktiveras, och se hur den fungerar korrekt.
- Genomför och överför ändringarna till integreringsmiljön. Detta skulle utlösa distributionsprocessen. Distributionen har slutförts.
- Kör scenariot 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
Ett fel uppstod när felmeddelandet om att din klass inte kan sparas i katalogen generated/code
visades.
Orsak
Orsaken till problemet är att klassen som du är beroende av inte genereras under distributionen och inte kan genereras senare när klassen aktiveras, eftersom katalogen generated/code
inte kan skrivas när distributionen är klar.
Det finns två huvudorsaker till detta:
- Fall 1: Klassen med beroenden för automatiskt genererade klasser finns i startpunkten (som
index.php
), som inte genomsöks efter beroenden under distributionen. - Fall 2: Beroendet till den automatiskt genererade klassen anges direkt (jämfört med den rekommenderade användningen av konstruktorn för att deklarera beroende).
Lösning
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
:
<?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
Du måste göra följande:
-
Flytta klassdefinitionen till
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... }
-
Redigera startpunkten
my_api/index.php
så att den ser ut så här: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
Specifik lösning för fall 2
Flytta beroendedeklarationen till konstruktorn.
Exempel
Ursprunglig klassdeklaration:
<?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...
}
Du måste ändra konstruktorn så här:
<?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...
}
Relaterad läsning
- Kodgenerering i utvecklardokumentationen.