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

この記事では、依存関係を指定した方法でクラスが即座に自動生成されず、クラスを生成/コードディレクトリ​に保存できないエラーメッセージが表示される問題を修正する方法について説明します。

説明 description

環境

Adobe Commerce on cloud infrastructure 2.2.0以降

問題/症状

再現手順:

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

期待される結果:

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

実際の結果

エラーメッセージ「クラスを生成/コードディレクトリ​に保存できません」が表示され、エラーが発生しました。

根本原因

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

これが起こる主な理由は2つあります。

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

解決策 resolution

どちらの場合も、自動生成されたクラスではなく、実際のファクトリを作成することが一般的な解決策です。 または、各ケースに特定のソリューションがあります。

ケース 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
experience-cloud-kcs-help-kbarticles