You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在禁用ObjectManager实例的合规前提下获取分类名称、ID及详情

Great question! Ditching direct ObjectManager calls is exactly how you should build Magento 2 code—it keeps things testable, maintainable, and aligned with the framework's core principles. Let’s break down the proper ways to fetch category data (name, ID, and more) without touching ObjectManager::getInstance().

Magento 2 is built around dependency injection, so injecting the right category-related interface or class into your constructor is the cleanest method. We’ll use interfaces where possible (following the dependency inversion principle) to make your code more flexible.

Scenario 1: Fetch a Single Category (e.g., in a Block or Controller)

Use Magento\Catalog\Api\CategoryRepositoryInterface to fetch a category by ID, or get the current category on a category page.

Example in a Block:

<?php
namespace Your\CustomModule\Block;

use Magento\Framework\View\Element\Template;
use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Registry;

class CategoryDetails extends Template
{
    protected $categoryRepository;
    protected $coreRegistry;

    // Inject dependencies via constructor
    public function __construct(
        Template\Context $context,
        CategoryRepositoryInterface $categoryRepository,
        Registry $coreRegistry,
        array $data = []
    ) {
        $this->categoryRepository = $categoryRepository;
        $this->coreRegistry = $coreRegistry;
        parent::__construct($context, $data);
    }

    // Get category data by ID
    public function getCategoryById(int $categoryId): ?array
    {
        try {
            $category = $this->categoryRepository->get($categoryId);
            return [
                'id' => $category->getId(),
                'name' => $category->getName(),
                'url_key' => $category->getUrlKey(),
                'description' => $category->getDescription(),
                'is_active' => $category->isActive(),
                'parent_id' => $category->getParentId()
            ];
        } catch (NoSuchEntityException $e) {
            // Handle missing category (log it, return null, etc.)
            return null;
        }
    }

    // Get the current category (if on a category listing page)
    public function getCurrentCategory(): ?array
    {
        $currentCategory = $this->coreRegistry->registry('current_category');
        if (!$currentCategory) {
            return null;
        }
        return $this->getCategoryById($currentCategory->getId());
    }
}

Example in a Controller:

<?php
namespace Your\CustomModule\Controller\Category;

use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Controller\Result\JsonFactory;

class GetData extends Action
{
    protected $categoryRepository;
    protected $resultJsonFactory;

    public function __construct(
        Context $context,
        CategoryRepositoryInterface $categoryRepository,
        JsonFactory $resultJsonFactory
    ) {
        $this->categoryRepository = $categoryRepository;
        $this->resultJsonFactory = $resultJsonFactory;
        parent::__construct($context);
    }

    public function execute()
    {
        $categoryId = $this->getRequest()->getParam('category_id');
        $result = $this->resultJsonFactory->create();

        if (!$categoryId) {
            return $result->setData(['error' => 'Category ID parameter is missing']);
        }

        try {
            $category = $this->categoryRepository->get($categoryId);
            return $result->setData([
                'id' => $category->getId(),
                'name' => $category->getName(),
                'level' => $category->getLevel(),
                'url_path' => $category->getUrlPath()
            ]);
        } catch (NoSuchEntityException $e) {
            return $result->setData(['error' => 'Category not found']);
        }
    }
}

Scenario 2: Fetch Multiple Categories (Category Collection)

If you need a list of categories (e.g., all active top-level categories), use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory to build a collection.

Example in a Model/Helper:

<?php
namespace Your\CustomModule\Model;

use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;

class CategoryList
{
    protected $categoryCollectionFactory;

    public function __construct(CollectionFactory $categoryCollectionFactory)
    {
        $this->categoryCollectionFactory = $categoryCollectionFactory;
    }

    // Get all active top-level categories
    public function getActiveTopLevelCategories(): array
    {
        $collection = $this->categoryCollectionFactory->create()
            ->addAttributeToSelect(['name', 'id', 'url_key'])
            ->addAttributeToFilter('is_active', 1)
            ->addAttributeToFilter('level', 2) // Top-level categories are level 2 (root is level 1)
            ->setOrder('position', 'ASC');

        $categoryList = [];
        foreach ($collection as $category) {
            $categoryList[] = [
                'id' => $category->getId(),
                'name' => $category->getName(),
                'url_key' => $category->getUrlKey()
            ];
        }
        return $categoryList;
    }
}
2. Why Avoiding ObjectManager::getInstance() Is Critical

Just to reinforce why this rule exists (since you mentioned it’s widely accepted):

  • Testability: Direct ObjectManager calls make unit testing impossible—you can’t mock dependencies to isolate your code.
  • Maintainability: It bypasses Magento’s DI configuration, so other developers can’t easily track where dependencies are used or modify them via di.xml.
  • Compatibility: Magento’s DI container handles proxies, caching, and class instantiation rules. Skipping it can lead to unexpected behavior (e.g., duplicate instances, missing lazy loading).

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:17:27