Å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:

  1. I den lokala miljön skriver du en anpassad klass med ett beroende på den automatiskt genererade klassen.
  2. Kör scenariot där din anpassade klass utlöses och se hur den fungerar.
  3. Genomför och överför ändringarna till integreringsmiljön. Detta skulle utlösa distributionsprocessen. Distributionen har slutförts.
  4. 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:

  1. 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...        }
    
  2. Redigera startpunkten my_api/index.php så 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.

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