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>

더 많은 코드를 보여주고 수행하려는 작업에 대한 더 많은 컨텍스트를 제공 할 수 있습니까?
Nathan Toombs

같은 문제가 발생했습니다. 그러나 위의 솔루션은 저에게 효과적이지 않습니다. 이것은 몇 주 동안 저를 당황하게했습니다.
Stevenlavine

답변:


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있습니다. 그러나 내가 그것을 언급하면 ​​주제에서 다시 예외가 있습니다.
Bartosz Kubicki

13
\Magento\Framework\App\Area::AREA_*하드 코딩 된 문자열 대신 상수를 사용해야합니다
7ochem

3
생성자에서 지역 코드를 설정하지 않는 것이 가장 좋습니다. 실행할 때마다 bin/magento 모든 생성자가 실행되고 지역 번호를 2 번 설정하려고하면 예외가 발생합니다. execute()상태가 필요한 경우 -method 에서 지역 코드를 설정하거나 상점 또는 지역 에뮬레이션에서 코드를 실행하는 것이 좋습니다. 또한 : 체인을 통해 세션을 트리거 할 수있는 생성자 종속성은 팩토리 또는 프록시를 사용하여 초기화되어 종속성이 지역 코드를 설정하지 않도록해야합니다.
Giel Berkers

1
정답으로 설정을 해제하십시오. 생성자에서 지역 코드를 설정하면 예외가 발생합니다.
Sandipan S

33

나는 오늘이 문제에 다시 부딪 쳤고 체인 아래의 종속성이 응용 프로그램의 상태를 알아야하는 인스턴스를 시작할 때 마다이 문제가 발생한다는 것을 알아야합니다.

대부분의 경우이 오류는 세션에 바인딩됩니다 (세션이 응용 프로그램 상태 (프론트 엔드 또는 관리 HTML)를 알아야하기 때문에).

필자의 경우 Magento\Tax\Api\TaxCalculationInterfaceCLI 명령을 사용해야했지만 고객 세션의 종속성 체인 (고객 그룹을 가져 오는 것)이 필요합니다.

편집 : 프록시를 사용하여 더 나은 솔루션을 찾았습니다. 그러나 역사를 위해 이전의 대답은 다음과 같습니다.


이 문제를 해결하기 위해 생성자 에이 인터페이스를 포함시키지 않고 공장입니다.

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

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

이런 식으로 클래스는 내가 필요한 하나의 메소드에서만 인스턴스화되고 더 이상 생성자에서는 인스턴스화되지 않습니다.

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

이것은이 특별한 경우에 나를 위해 문제를 해결했습니다.


그리고 이제 프록시를 사용하는 대답 :

체인 아래로 모든 종속성을 트리거하지 않으려면 생성자에서 프록시를 사용해야합니다. 원본 문서 에 따르면 :

... 생성자 주입은 또한 객체를 생성 할 때 객체 인스턴스화의 연쇄 반응이 종종 발생한다는 것을 의미합니다.

과:

... 프록시는 다른 클래스를 확장하여 지연로드 된 버전으로 만듭니다. 즉, 클래스의 메소드 중 하나가 실제로 호출 된 후에 만 ​​프록시가 확장하는 클래스의 실제 인스턴스입니다.

따라서 내 상황에서을 사용하면 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;
}

이렇게하면 내 수업이 게으르게로드됩니다. 즉, 메소드 중 하나를 호출하자마자 인스턴스화됩니다. 예를 들면 다음과 같습니다.

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

17

당신은 사용하지 말아야 setAreaCode에서 __constructCLI 명령에 대한. Magento 명령을 실행하면 응용 프로그램에 등록 된 각 스크립트에 대한 인스턴스를 수집하고 생성합니다. __construct지역 코드 정의 가 둘 이상인 경우 오류가 발생합니다.

execute()지역 코드를 설정 하는 방법 을 사용하는 것이 좋습니다 . 카탈로그 모듈을 확인하십시오. vendor/magento/module-catalog/Console/Command/ImagesResizeCommand.php


1
이해가 되네요 다른 사람이 이것에 대한 의견을 추가하고 싶습니까?
ermannob

이것은 맞습니다. 허용되는 답변에 대한 내 의견을 참조하십시오. 생성자에서 지역 번호를 설정하지 않는 것이 가장 좋습니다. 실행할 때마다 bin/magento 모든 생성자가 실행되고 지역 번호를 2 번 설정하려고하면 예외가 발생합니다. execute()상태가 필요한 경우 -method 에서 지역 코드를 설정하거나 상점 또는 지역 에뮬레이션에서 코드를 실행하는 것이 좋습니다. 또한 : 체인을 통해 세션을 트리거 할 수있는 생성자 종속성은 팩토리 또는 프록시를 사용하여 초기화되어 종속성이 지역 코드를 설정하지 않도록해야합니다.
Giel Berkers

그러나 Magento 2.2에서는 명령 클래스 구문에 \ Magento \ Sales \ Api \ Data \ OrderInterface 또는 \ Magento \ Sales \ Api \ OrderManagementInterface를 주입하면 Magento \ Framework \ Session \ SessionManager-> __ construct ()가 호출되고 "영역이 아님" 세트". 이것은 일어나지 않습니다 2.1. 2.2에서 module-ui / Config / Reader / Definition / Data가 도입 되었기 때문에 어떻게 해결할 수 있습니까?
Doni Wibowo

4

이 areaCode 문제에 대해 'frontend'매개 변수가 작동하지 않으면 다음을 시도하십시오.

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

나를 위해 일하고 있었으면 좋겠다.


이 코드를 어떤 파일에 추가해야합니까? 나는 정확히 같은 문제가 있습니다.
Magento Learner

@xxx 사용자 정의 명령 으로이 문제가 발생했기 때문에 내가 만든 명령 파일 에이 문제를 썼습니다. 다음과 같이 execute 함수에 추가 할 수 있습니다.try { $this->_state->... } finally { $this->executeMyCommand() }
DependencyHell

4

대부분의 경우 콘솔 명령에서 수행 된 일부 작업으로 인해 예외가 발생합니다. 해결 방법 (지역 번호 설정 대신)은 지역 번호를 에뮬레이트하고 다음을 사용하여 작업을 수행하는 것입니다.

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

$state객체는 어디에 있습니까 Magento\Framework\App\State? 다른 장소에 영역을 설정하면 통화간에 충돌이 발생할 수 있으므로 문제가됩니다.


이 참조를 사용하고 있으며 유사한 오류가 발생합니다. 지역 코드가 이미 컨트롤러에 설정되어 있습니다.이 문제를 해결하도록 도와 줄 수 있습니까? 내 생성 함수에서 setareacode를 호출하는 것과 같은 변경을했지만 동일한 오류가 발생합니다.
Gagan


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

에서 젠토 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

그런 다음 모든 타사 모듈을 다시 활성화하고 동일한 명령을 실행했습니다. 문제가 해결되었습니다. 이것이 도움이되기를 바랍니다.


이것은 실제로 해결책이 아닙니다. 깔개 밑에 먼지가 숨겨져 있습니다. 그러나 어쨌든 잘 찾으십시오. 개발 과정에서 도움이되지만 문제가 해결되지는 않습니다.
Marius

마리우스에게 고쳐 줘서 고마워 대부분의 프로젝트에서 동일한 사례를 찾았으며이를 해결하는 데 도움이됩니다.
Ravi 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.