「生成/コードディレクトリにクラスを保存できません」エラーを修正
この記事では、依存関係を指定した方法でクラスが即座に自動生成されず、クラスを生成/コードディレクトリに保存できないエラーメッセージが表示される問題を修正する方法について説明します。
説明 description
環境
Adobe Commerce on cloud infrastructure 2.2.0以降
問題/症状
再現手順:
- ローカル環境で、自動生成されたクラスに依存するカスタムクラスを記述します。
- カスタムクラスがトリガーされるシナリオを実行し、正しく動作することを確認します。
- 統合環境に変更をコミットしてプッシュします。 これにより、デプロイメントプロセスがトリガーされます。 デプロイが成功しました。
- 統合環境で、カスタムクラスがトリガーされるシナリオを実行します。
期待される結果:
すべてが正しく機能し、ローカル環境と同じように機能します。
実際の結果
エラーメッセージ「クラスを生成/コードディレクトリに保存できません」が表示され、エラーが発生しました。
根本原因
この問題の原因は、依存関係があるクラスがデプロイメント中に生成されず、デプロイメントが完了した後に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
次の手順を実行する必要があります。
-
クラス定義を
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... } -
次のように表示されるように、エントリポイント
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...}
関連トピックス
開発者ドキュメントの コード生成。