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

  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 aktiveras, och se hur den fungerar korrekt.
  3. Genomför och överför ändringarna till integreringsmiljön. Detta skulle utlösa distributionsprocessen. Distributionen har slutförts.
  4. 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:

  1. 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...
        }
    
  2. 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

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