「生成された/コードディレクトリにクラスを保存できません」エラーを修正しました

この記事では、依存関係を指定した方法によりクラスがその場で自動生成されなくなり、Class cannot be saved in the generated/code directory エラーメッセージが表示される問題を修正する方法を説明します。

説明 description

環境

クラウドインフラストラクチャー 2.2.0 以降でのAdobe Commerce

問題/症状

再現手順:

  1. ローカル環境で、自動生成されたクラスに依存するカスタムクラスを作成します。
  2. カスタムクラスがトリガーされるシナリオを実行し、正しく機能していることを確認します。
  3. 変更をコミットして統合環境にプッシュします。 これにより、デプロイメントプロセスがトリガーになります。 デプロイメントに成功しました。
  4. 統合環境で、カスタムクラスがトリガーされるシナリオを実行します。

期待される結果:

ローカル環境と同様に、すべてが正しく機能します。

実際の結果

クラスを生成された/コードディレクトリに保存できない というエラーメッセージで失敗しました。

根本原因

この問題の原因は、依存関係があるクラスがデプロイメント中に生成されず、クラスがトリガーされたときに、その場で生成できないことです。デプロイが完了すると、generated/code ディレクトリを書き込めなくなるからです。

この問題が発生する主な理由は次の 2 つです。

ケース 1: 自動生成されたクラスに対して依存関係を持つクラスは、デプロイメント中に依存関係をスキャンされないエントリポイント(index.php など)にあります。
ケース 2: 自動生成クラスの依存関係が直接指定されている(依存関係を宣言するコンストラクターの推奨使用方法と比較)。

解決策 resolution

どちらの場合にも共通する解決策の 1 つは、自動生成されたクラスではなく、実際のファクトリを作成することです。 または、ケースごとに特定の解決策があります。

事例 1 固有の解決策

クラス コードをエントリ ポイントから別のモジュールに移動し、エントリ ポイントで使用します。

例:

内の元のコード(例: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

次の手順を実行する必要があります。

  1. クラス定義を 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. エントリ ポイント my_api/index.php を次のように編集します。

    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
    

事例 2)特有の解決策

依存関係宣言をコンストラクターに移動します。

例:

元のクラス宣言:

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

コンストラクタは、次のように変更する必要があります。

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

関連資料

開発者向けドキュメントの ​ コードの生成 ​

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