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

この記事では、依存関係を指定した方法によりクラスがその場で自動生成されなくなり、「生成/コードディレクトリにクラスを保存できません というエラーメッセージが表示される問題を修正する方法を説明し す。

影響を受ける製品とバージョン

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

問題

再現手順

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

期待される結果

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

実際の結果

クラスを generated/code ディレクトリに保存できないというエラーメッセージで失敗しました。

原因:

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

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

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

解決策

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

または、ケースごとに特定の解決策があります。

事例 1 固有の解決策

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

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

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

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

    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
    

事例 2)特有の解決策

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

元のクラス宣言:

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

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

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

関連資料

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