Error "La clase no se puede guardar en el directorio de códigos"

Este artículo describe cómo solucionar el problema en el que la forma en que especificó las dependencias impide que las clases se generen automáticamente sobre la marcha y se obtiene el mensaje de error "La clase no se puede guardar en el directorio generated/code".

Productos y versiones afectados

  • Adobe Commerce en la infraestructura en la nube 2.2.0 o posterior

Problema

Pasos a seguir

  1. En su entorno local, escriba una clase personalizada con una dependencia en la clase generada automáticamente.
  2. Ejecute el escenario en el que se activa la clase personalizada y vea que funciona correctamente.
  3. Confirme e inserte sus cambios en el entorno de integración. Esto almacenaría en déclencheur el proceso de implementación. La implementación es correcta.
  4. En el entorno de integración, ejecute el escenario donde se activará la clase personalizada.

Resultado esperado

Todo funciona correctamente, del mismo modo que en su entorno local.

Resultado real

Error con el mensaje de error que indica que la clase no se puede guardar en el directorio generated/code.

Causa

La causa del problema es que la clase de la que depende no se genera durante la implementación y no se puede generar más adelante cuando se activa la clase, ya que el directorio generated/code no está disponible para escribir una vez completada la implementación.

Esto puede deberse a dos razones principales:

  • Caso 1: La clase con dependencias en clases generadas automáticamente se encuentra en el punto de entrada (como index.php ), que no se analiza para detectar dependencias durante la implementación.
  • Caso 2: La dependencia de la clase generada automáticamente se especifica directamente (compárela con el uso recomendado del constructor para declarar la dependencia).

Solución

Una solución común para ambos casos sería crear una fábrica real en lugar de la clase generada automáticamente.

O hay una solución particular para cada caso.

Caso 1 solución específica

Mueva el código de clase desde el punto de entrada a un módulo independiente y, a continuación, utilícelo en el punto de entrada.

Ejemplo

Código original en, por ejemplo, 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

Debe seguir estos pasos:

  1. Mover la definición de clase a 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. Edite el punto de entrada my_api/index.php para que tenga el siguiente aspecto:

    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
    

Caso 2 solución específica

Mueva la declaración de dependencia al constructor.

Ejemplo

Declaración de clase original:

<?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...
}

Debe cambiar su constructor de la siguiente manera:

<?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...
}

Lectura relacionada

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