Magento 2のカスタムCLIコマンドの「エリアコードが設定されていません」問題


46

データの更新中に次のエラーが発生します CustomerRepositoryInterface

[Magento\Framework\Exception\SessionException]  
Area code not set: Area code must be set before starting a session.

[Magento\Framework\Exception\LocalizedException]  
Area code is not set                              

以下は私のdi.xmlファイルです

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\Console\CommandList">
        <arguments>
            <argument name="commands" xsi:type="array">
                <item name="test1_command" xsi:type="object">Test\Module\Console\Command\Test1Command</item>
                <item name="test2_command" xsi:type="object">Test\Module\Console\Command\Test2Command</item>
            </argument>
        </arguments>
    </type>
</config>

あなたのコードをもっと見せて、あなたがやろうとしていることについてより多くのコンテキストを教えてください。
ネイサントゥームズ

同じ問題が発生しています。しかし、上記のソリューションは私には機能しません。これは何週間も私を困惑させてきました。
スティーブンラビン

回答:


63

エリアはMagento CLIで設定されていません(コアコマンドには必要ありません)。コマンドのexecuteメソッドの最初に設定できます:

/** @var \Magento\Framework\App\State **/
private $state;

public function __construct(\Magento\Framework\App\State $state) {
    $this->state = $state;
    parent::__construct();
}

public function execute() {
    $this->state->setAreaCode(\Magento\Framework\App\Area::AREA_FRONTEND); // or \Magento\Framework\App\Area::AREA_ADMINHTML, depending on your needs
}

6
参考までに、あなたは「adminhtml」が私のために働いていませんでした。「管理者」が働いた。
Phoenix128_RiccardoT

私にとってはそれは機能しません(adminまたはadminhtml)-エラーがあります:Area code already set。しかし、その後、コメントアウトすると、主題からの例外が再びあります。
バルトシュKubicki

13
\Magento\Framework\App\Area::AREA_*ハードコードされた文字列の代わりに定数を使用する必要があります
-7ochem

3
コンストラクターで市外局番を設定しないことをお勧めします。実行するたびにbin/magento すべてのコンストラクターが実行され、エリアコードが2回設定されようとすると、例外がスローされます。execute()状態が必要な場合は、-methodで市外局番を設定するか、ストアまたはエリアエミュレーションでコードを実行することをお勧めします。また、チェーンをたどってセッションをトリガーする可能性のあるコンストラクターの依存関係は、ファクトリーまたはプロキシーを使用して初期化し、依存関係がエリアコードを設定しないようにする必要があります。
ギールバーカー

1
正解として設定を解除してください。コンストラクターで市外局番を設定すると、例外が作成されます。
サンディパンS

33

今日、この問題に再び出くわしました。チェーンの下位の依存関係がアプリケーションの状態を知る必要があるインスタンスを開始するたびに、この問題がスローされることを知っておくことが重要です。

多くの場合、このエラーはセッションに依存しています(セッションはアプリケーションの状態(フロントエンドまたはadminhtml)を知る必要があるため)。

私の場合Magento\Tax\Api\TaxCalculationInterface、CLIコマンドを使用する必要がありましたが、これには依存関係チェーンのある時点で顧客セッション(おそらく顧客グループを取得するため)が必要です。

編集:プロキシを使用してより良いソリューションを見つけました。しかし、歴史のために、ここに私の以前の答えがあります:


これを解決するために、コンストラクターにこのインターフェースを含めませんでしたが、むしろファクトリーです。

/**
 * @var \Magento\Tax\Api\TaxCalculationInterfaceFactory
 */
protected $taxCalculationFactory;

/**
 * @param \Magento\Tax\Api\TaxCalculationInterfaceFactory $taxCalculationFactory
 */
public function __construct(
    \Magento\Tax\Api\TaxCalculationInterfaceFactory $taxCalculationFactory
) {
    $this->taxCalculationFactory = $taxCalculationFactory;
}

このようにして、クラスは必要な1つのメソッドでのみインスタンス化され、コンストラクターではインスタンス化されません。

$taxCalculation = $this->taxCalculationFactory->create();

これにより、この特定のケースで問題が解決しました。


そして今、プロキシを使用した答え:

チェーンのすべての依存関係をトリガーしたくない場合は、コンストラクターでプロキシを使用する必要があります。オリジナルのドキュメントによると:

...コンストラクター注入は、オブジェクトを作成するときに、オブジェクトのインスタンス化の連鎖反応がしばしば結果であることも意味します。

そして:

...プロキシは他のクラスを拡張して、それらの遅延ロードバージョンになります。つまり、クラスのメソッドの1つが実際に呼び出された後にのみ、プロキシが拡張するクラスの実際のインスタンスが作成されます。

だから、私の状況では、でTaxCalculationInterface、私がしなければならなかったのは、私のコンストラクタで税計算をプロキシとしてインスタンス化するだけでした:

/**
 * @var \Magento\Tax\Api\TaxCalculationInterface\Proxy
 */
protected $taxCalculation;

/**
 * @param \Magento\Tax\Api\TaxCalculationInterface\Proxy $taxCalculation
 */
public function __construct(
    \Magento\Tax\Api\TaxCalculationInterface\Proxy $taxCalculation
) {
    $this->taxCalculation = $taxCalculation;
}

このように、私のクラスは遅延ロードされます。つまり、メソッドの1つを呼び出すとすぐにインスタンス化されます。例えば:

$rate = $this->taxCalculation->getCalculatedRate($productRateId);

17

for CLIコマンドsetAreaCodeでは使用しないでください__construct。コマンドを実行すると、Magentoはアプリケーションに登録されている各スクリプトのインスタンスを収集して作成します。__construct市外局番の定義が複数ある場合、エラーが発生します。

execute()メソッドを使用して市外局番を設定した方が良いと思います。カタログモジュールを確認します。 vendor/magento/module-catalog/Console/Command/ImagesResizeCommand.php


1
私には理にかなっています。他に誰かがこれにコメントを追加したいですか?
エルマンノブ

これは正しいです。受け入れられた答えに対する私のコメントも参照してください。コンストラクターで市外局番を設定しないことが最善です。実行するたびに、bin/magento すべてのコンストラクターが実行され、エリアコードが2回設定されようとすると、例外がスローされます。execute()状態が必要な場合は、-methodで市外局番を設定するか、ストアまたはエリアエミュレーションでコードを実行することをお勧めします。また、チェーンをたどってセッションをトリガーする可能性のあるコンストラクターの依存関係は、ファクトリーまたはプロキシーを使用して初期化し、依存関係がエリアコードを設定しないようにする必要があります。
ギールバーカー

しかし、Magento 2.2では、コマンドクラスの構造に\ Magento \ Sales \ Api \ Data \ OrderInterfaceまたは\ Magento \ Sales \ Api \ OrderManagementInterfaceを挿入すると、Magento \ Framework \ Session \ SessionManager-> __ construct()が呼び出され、「area notセットする"。これは起こりません2.1。module-ui / Config / Reader / Definition / Dataは2.2で導入されているため、これをどのように解決すればよいでしょうか?
ドニウィボボ

4

このareaCodeの問題で、「frontend」パラメーターが機能しない場合は、以下を試してください。

$this->_state->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL);

私のために働いていた、それが役立つことを願って


どのファイルにこのコードを追加する必要がありますか?私はまったく同じ問題を抱えています。
Magentoの学習

@xxxカスタムコマンドからこの問題が発生したため、作成したコマンドファイルにこれを記述しました。次のようなものを使用して、execute関数に追加できますtry { $this->_state->... } finally { $this->executeMyCommand() }
DependencyHell

4

ほとんどの場合、例外はコンソールコマンドで実行される一部のアクションが原因です。(市外局番を設定する代わりに)解決策は、市外局番をエミュレートし、次を使用してアクションを実行することです。

$this->state->emulateAreaCode(Area::AREA_ADMINHTML, [$this, 'someAction'], []);

はの$stateオブジェクトですMagento\Framework\App\State。別の場所にエリアを設定すると、呼び出し間で競合が発生する可能性があるため、問題です。


私はこの参照を使用していますが、同様のエラーが発生していますエリアコードはすでにコントローラーに設定されています。これから抜け出すのを手伝ってください。コンストラクト関数でsetareacodeを呼び出すなどの変更を加えましたが、同じエラーが発生します。
ガガン


1

問題は、変数area_codeが設定されていない場合にfalseを返すメソッドがないことです。解決するために私が見つけた方法は、状態クラスのオーバーライドを作成し、area_codeが設定されているかどうかを検証する新しいメソッドを作成することでした。

私のファイルdi.xmlで

    <preference for="Magento\Framework\App\State" type="Webjump\Abacos\App\State" />

CreateadファイルWebjump \ Abacos \ App \ State

namespace Webjump\Abacos\App;

class State extends \Magento\Framework\App\State
{
    public function validateAreaCode()
    {
        if (!isset($this->_areaCode)) {
            return false;
        }
        return true;
    }
}

つかいます

/**
* @var \Magento\Framework\App\State
*/
protected $state;

public function __construct(
            \Magento\Framework\App\State $state
)
{
$this->state = $state;
if (!$this->state->validateAreaCode()) {
 $this->state->setAreaCode(\Magento\Framework\App\Area::AREA_ADMINHTML);
}
}

1

Magentoの2あなたは設定されている場合AreadCodeをまだこのエラーは、コード、次の試してみてください取得します。

  • つかいます Magento\Framework\App\Bootstrap;
  • 含める app/bootstrap.php;
  • $ bootstrap = Bootstrap::create(BP, $_SERVER);
  • $ objectManager = $bootstrap->getObjectManager();
  • $ state = $objectManager->get('Magento\Framework\App\State');
  • $ state-> setAreaCode( 'global');

0

bin/magento setup:upgrade本番からデータベースをインポートした後、「エリアコードが設定されていません」というエラーが発生しました。このトピックの主題とは少し異なるケースですが、誰かを助けるかもしれません。bin/magento deploy:mode:set developer既に開発者モードになっていたにもかかわらず、ローカルで実行されているこの問題を解決できました。Magentoはいくつかの設定を調整しましたが、特に私にとってはdebug_loggingが役割を果たしました。


0

プロキシクラスを使用して解決策を得ました。例は

use Klevu\Search\Model\Product\MagentoProductActionsInterface\Proxy as MagentoProductActionsInterface;

public function __construct(
        MagentoProductActionsInterface $magentoProductActionsInterface
    )
    {
        $this->_magentoProductActionsInterface = $magentoProductActionsInterface;
        parent::__construct();
    }

これは私の問題を修正しました


-1

セットアップのアップグレード中に、エリアコードで同じ問題が見つかりました。

Module 'Magento_WebsiteRestriction':Installing data... Area code not set: Area code must be set before starting a session

すべてのサードパーティモジュールを無効にして実行します setup:upgrade

次に、すべてのサードパーティモジュールを再度有効にし、同じコマンドを実行しました。問題が解決したこれがあなたの助けになることを願っています。


これは実際には解決策ではありません。敷物の下に汚れが隠れているだけです。とにかく良い発見。開発プロセス中に役立つはずですが、問題がなくなるわけではありません。
マリウス

マリウス、私を修正してくれてありがとう。私はほとんどのプロジェクトで同じケースを見つけましたが、これはこれを解決するのに役立ちます。
ラヴィyadav

@Marius、理由を説明し、問題を解決するための最も標準的な方法を人々に知らせたいですか?
chrBrd

-1

セッションとアプリの「エリアコードが定義されていません」よりもCLIを使用してmagentoをアップグレードしてみてくださいvendor/magento/framework/App/State.php

public function __construct(
    \Magento\Framework\Config\ScopeInterface $configScope,
    $mode = self::MODE_DEFAULT
) {
    $this->_areaCode = Area::AREA_GLOBAL;
    $this->_configScope = $configScope;
    switch ($mode) {
        ...
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.