Vấn đề 'Mã vùng không được đặt' trong các lệnh CLI tùy chỉnh trong Magento 2


46

Tôi đang gặp lỗi sau khi cập nhật dữ liệu 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                              

Sau đây là di.xmltập tin của tôi

<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>

Bạn có thể vui lòng hiển thị thêm mã của bạn và cung cấp thêm ngữ cảnh như những gì bạn đang cố gắng làm không?
Toombs

Tôi đang gặp vấn đề tương tự. Tuy nhiên, giải pháp hiển thị ở trên không hiệu quả với tôi. Điều này đã làm tôi bối rối trong nhiều tuần nay.
Stevenlavine

Câu trả lời:


63

Khu vực này không được đặt trong Magento CLI (không bắt buộc đối với bất kỳ lệnh cốt lõi nào). Nó có thể được đặt ở đầu executephương thức lệnh của bạn :

/** @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
FYI, bạn "adminhtml" không làm việc cho tôi. "Quản trị viên" đã làm việc.
Phoenix128_RiccardoT

Đối với tôi nó không hoạt động ( adminhoặc adminhtml) - có lỗi : Area code already set. Nhưng sau đó, nếu tôi nhận xét nó ra thì có ngoại lệ từ chủ đề một lần nữa.
Bartosz Kubicki

13
Bạn nên sử dụng \Magento\Framework\App\Area::AREA_*hằng số thay vì chuỗi mã hóa cứng
7ochem

3
Tốt nhất không nên đặt mã vùng trong hàm tạo của bạn; Bất cứ khi nào bạn chạy bin/magento tất cả các hàm tạo được thực thi và nếu mã vùng được thử đặt 2 lần thì một ngoại lệ sẽ được ném. Tốt hơn là đặt mã vùng trong đối execute()xứng của bạn hoặc chạy mã của bạn trong mô phỏng cửa hàng hoặc khu vực nếu trạng thái được yêu cầu. Ngoài ra: các phụ thuộc của hàm tạo có thể kích hoạt một phiên xuống chuỗi nên được khởi tạo bằng cách sử dụng một nhà máy hoặc proxy để ngăn chặn các phụ thuộc thiết lập mã vùng.
Giel Berkers

1
Xin vui lòng bỏ đặt nó là một câu trả lời chính xác. Nó tạo ra ngoại lệ khi chúng ta đặt mã vùng trong hàm tạo.
Sandipan S

33

Tôi đã vấp phải vấn đề này một lần nữa ngày hôm nay và điều quan trọng là phải biết rằng vấn đề này được đưa ra bất cứ khi nào một sự phụ thuộc xuống chuỗi khởi tạo một thể hiện cần biết trạng thái của ứng dụng.

Trong nhiều trường hợp, lỗi này bị ràng buộc theo phiên (vì phiên cần biết trạng thái của ứng dụng (frontend hoặc adminhtml)).

Trong trường hợp của tôi, tôi cần phải có Magento\Tax\Api\TaxCalculationInterfacemột lệnh CLI, nhưng điều này đòi hỏi tại một số điểm trong chuỗi phụ thuộc đó là phiên khách hàng (có thể để có được nhóm khách hàng).

Chỉnh sửa: Tôi tìm thấy một giải pháp tốt hơn bằng cách sử dụng proxy. Nhưng vì lợi ích của lịch sử, đây là câu trả lời trước đây của tôi:


Để giải quyết vấn đề này, tôi đã không đưa giao diện này vào công cụ xây dựng của mình, mà là nhà máy của nó:

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

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

Theo cách này, lớp chỉ được khởi tạo trong một phương thức mà tôi cần nó và không còn trong hàm tạo:

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

Điều này đã giải quyết vấn đề cho tôi trong trường hợp cụ thể này.


Và bây giờ câu trả lời bằng proxy:

Nếu bạn không muốn kích hoạt tất cả các phụ thuộc trong chuỗi, bạn nên sử dụng proxy trong hàm tạo của mình. Theo tài liệu gốc :

... tiêm constructor cũng có nghĩa là một phản ứng dây chuyền khởi tạo đối tượng thường là kết quả khi bạn tạo một đối tượng.

và:

... Proxy mở rộng các lớp khác để trở thành phiên bản lười biếng của chúng. Đó là, một thể hiện thực của lớp mà một proxy mở rộng chỉ được tạo sau khi một trong các phương thức của lớp thực sự được gọi.

Vì vậy, trong tình huống của tôi, với TaxCalculationInterfacetất cả, tất cả những gì tôi phải làm là khởi tạo tính toán thuế của mình dưới dạng proxy trong công cụ xây dựng của mình:

/**
 * @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;
}

Bằng cách này, lớp học của tôi là lười tải. Đó là: nó chỉ được khởi tạo ngay khi tôi gọi một trong các phương thức của nó. Ví dụ:

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

17

Bạn không nên sử dụng setAreaCodetrong các __constructlệnh CLI. Khi bạn chạy bất kỳ lệnh nào Magento thu thập và tạo phiên bản cho mỗi tập lệnh được đăng ký trong ứng dụng của bạn. Nếu có nhiều hơn một __constructđịnh nghĩa mã vùng, bạn sẽ gặp lỗi.

Tôi cho rằng tốt hơn để sử dụng execute()phương pháp để đặt mã vùng. Kiểm tra mô-đun danh mục: vendor/magento/module-catalog/Console/Command/ImagesResizeCommand.php


1
Có nghĩa với tôi. Bất cứ ai khác muốn thêm một nhận xét về điều này?
ermannob

Điều này là chính xác, xem thêm nhận xét của tôi về câu trả lời được chấp nhận: Tốt nhất không nên đặt mã vùng trong hàm tạo của bạn; Bất cứ khi nào bạn chạy bin/magento tất cả các hàm tạo được thực thi và nếu mã vùng được thử đặt 2 lần thì một ngoại lệ sẽ được ném. Tốt hơn là đặt mã vùng trong đối execute()xứng của bạn hoặc chạy mã của bạn trong mô phỏng cửa hàng hoặc khu vực nếu trạng thái được yêu cầu. Ngoài ra: các phụ thuộc của hàm tạo có thể kích hoạt một phiên xuống chuỗi nên được khởi tạo bằng cách sử dụng một nhà máy hoặc proxy để ngăn chặn các phụ thuộc thiết lập mã vùng.
Giel Berkers

nhưng trong Magento 2.2, việc tiêm \ Magento \ Sales \ Api \ Data \ OrderInterface hoặc \ Magento \ Sales \ Api \ OrderManloymentInterface trong các cấu trúc lớp lệnh sẽ gọi Magento \ Framework \ Session \ SessionManager -> __ construc () và sẽ không kết thúc " bộ". Điều này không xảy ra 2.1. bởi vì module-ui / Config / Reader / Định nghĩa / Dữ liệu được giới thiệu trong 2.2, làm thế nào để chúng ta giải quyết vấn đề này?
Doni Wibowo

4

đối với vấn đề Mã vùng này, nếu tham số 'frontend' không hoạt động, hãy thử:

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

đã làm việc cho tôi, hy vọng nó sẽ giúp


Trong tập tin nào tôi nên thêm mã này? Tôi có chính xác cùng một vấn đề.
Học viên Magento

@xxx Tôi gặp vấn đề này từ một lệnh tùy chỉnh, vì vậy tôi đã viết nó trong tệp lệnh tôi đã tạo. Bạn có thể thêm nó vào chức năng thực thi, với nội dung như sau:try { $this->_state->... } finally { $this->executeMyCommand() }
DependencyHell

4

Trong hầu hết các trường hợp, ngoại lệ là do một số hành động được thực hiện trong lệnh console. Giải pháp (thay vì đặt mã vùng) là mô phỏng mã vùng và thực hiện hành động bằng cách sử dụng

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

nơi $statelà đối tượng của Magento\Framework\App\State. Cài đặt khu vực ở vị trí khác nhau là một vấn đề, bởi vì nó có thể gây ra xung đột giữa các cuộc gọi.


Tôi đang sử dụng tài liệu tham khảo này và nhận được lỗi Mã vùng tương tự đã được đặt trong bộ điều khiển của tôi, bạn có thể vui lòng giúp tôi thoát khỏi điều này. Tôi đã thực hiện các thay đổi như, gọi setareacode trong hàm xây dựng của mình nhưng gặp lỗi tương tự.
Gagan


1

Vấn đề là nó không có bất kỳ phương thức nào trả về false nếu biến area_code chưa được đặt. Cách tôi tìm thấy nó để giải quyết là bằng cách tạo ghi đè của lớp trạng thái và tạo một phương thức mới để xác thực nếu area_code được đặt.

Trong tập tin của tôi

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

Tạo tệp tin 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;
    }
}

Sử dụng

/**
* @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

Trong magento 2 nếu bạn đặt AreadCode nhưng vẫn gặp lỗi này, vui lòng thử mã sau.

  • Sử dụng Magento\Framework\App\Bootstrap;
  • bao gồm app/bootstrap.php;
  • $ bootstrap = Bootstrap::create(BP, $_SERVER);
  • $ objectManager = $bootstrap->getObjectManager();
  • $ bang = $objectManager->get('Magento\Framework\App\State');
  • $ state-> setAreaCode ('toàn cầu');

0

Tôi đã bị lỗi 'Mã vùng không được đặt' chạy bin/magento setup:upgradesau khi nhập cơ sở dữ liệu từ sản xuất. Đó là một trường hợp hơi khác so với chủ đề này, nhưng có thể sẽ giúp được ai đó. Tôi đã có thể giải quyết vấn đề này khi chạy cục bộ bin/magento deploy:mode:set developermặc dù tôi đã ở chế độ nhà phát triển. Magento đã thực hiện một số điều chỉnh cấu hình, đặc biệt đối với tôi vai trò debug_logging.


0

Tôi đã có giải pháp bằng cách sử dụng lớp proxy. Ví dụ là

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

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

Điều này đã khắc phục vấn đề của tôi


-1

Tôi đã tìm thấy vấn đề tương tự với mã vùng trong khi nâng cấp thiết lập.

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

Tôi đã tắt tất cả các mô-đun của bên thứ ba và chạy setup:upgrade

Sau đó, tôi đã kích hoạt lại tất cả các mô-đun của bên thứ ba và chạy cùng một lệnh. Vấn đề được giải quyết cho tôi Hy vọng đây là sự giúp đỡ cho bạn.


đây không thực sự là một giải pháp. Nó chỉ che giấu bụi bẩn dưới tấm thảm. Nhưng dù sao cũng tìm thấy tốt. Nó sẽ giúp trong quá trình phát triển, nhưng nó không làm cho vấn đề biến mất.
Marius

Cảm ơn bạn Marius đã sửa chữa cho tôi. Tôi đã tìm thấy trường hợp tương tự trong hầu hết các dự án của tôi và điều này giúp tôi giải quyết điều này.
Ravi yadav

@Marius, bạn có quan tâm giải thích lý do và cho mọi người biết phương pháp kinh điển nhất để giải quyết vấn đề không?
chrBrd

-1

Cố gắng nâng cấp magento bằng CLI hơn tôi đã tìm thấy 'mã vùng không xác định' cho phiên & ứng dụng. Nhưng tôi không thể tìm thấy mô-đun hoặc chủ đề nào. Vì vậy, tôi chỉ thực hiện bên dưới các thay đổi trong vendor/magento/framework/App/State.phptệp và nó hoạt động.

public function __construct(
    \Magento\Framework\Config\ScopeInterface $configScope,
    $mode = self::MODE_DEFAULT
) {
    $this->_areaCode = Area::AREA_GLOBAL;
    $this->_configScope = $configScope;
    switch ($mode) {
        ...
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.