Magento 2:获取类别ID的父类别ID

如何获取Magento 2中类别ID的父类别ID?

在Magento 1中,我通过以下操作做到了这一点:

$product_id = 101; //for example
$product = Mage::getModel('catalog/product')->load($product_id); //get product object by product ID
$category_ids = $product->getcategoryIds(); //array of all categories that the product is in
foreach ($category_ids as $cat_ids) {
    $parent_id = Mage::getModel('catalog/category')->load($cat_id)->getParentId(); //
    echo $parent_id; //outputs an int ID of parent category
}

在Magento 2中,我一直在尝试以下操作:

$product_id = 101; //again,for example
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$productRepository = $objectManager->create('\Magento\Catalog\Model\ProductRepository');
$product = $productRepository->getById($product_id); //get product object by product ID
$category_ids = $product->getcategoryIds(); //array of all categories that the product is in
foreach ($category_ids as $cat_ids) {
    echo $cat_ids;
}

到目前为止,我的代码运行正常,并且$ category_ids是产品所在的所有类别的数组。但是,我无法弄清楚如何在$ category_ids中获取每个子类别ID的父类别ID。数组。

注意*我知道我不应该直接使用ObjectManager,所以请从您的答案中保存此内容。我正在寻求以这种方式专门使用ObjectManager来遍历$ category_ids并为每个子类别ID加载父类别ID。

gshj2003 回答:Magento 2:获取类别ID的父类别ID

经常这样做,有多种方法可以实现。

类别工厂路线

要直接加载类别,请通过负责\Magento\Catalog\Model\Category类的Factory Singleton进行加载。这是\Magento\Catalog\Model\CategoryFactory类。您可以从Category的每个实例中简单地调用方法getParentId()以获取父ID。

foreach ($categoryIds as $categoryId) {
    try {
        $category = $this->_categoryFactory->create()->load($categoryId);
    } catch (\Exception $e) {
        /* Handle this appropriately... */
    }
    echo 'Parent Category ID: ',$category->getParentId(),PHP_EOL;
}

在此示例中,$categoryIds是您从array实例中提取的类别ID的\Magento\Catalog\Model\Product

类别存储库路由

或者最好将\Magento\Catalog\Model\CategoryRepository类的Singleton实例用作Factory的包装器。它将处理所有加载并增加一些错误处理,还将存储对已加载类别的引用,以供以后重用。因此,如果您在一次执行中多次执行此操作,或者怀疑以后会加载同一类别,则使用Repository可以优化性能。

foreach ($categoryIds as $categoryId) {
    try {
        $category = $this->_categoryRepository->get($categoryId);
    } catch (\Exception $e) {
        /* Handle this appropriately... */
    }
    echo 'Parent Category ID: ',PHP_EOL;
}

收集路线

这应该是一条更快的路线,因为您(1)从数据库加载一次所有类别,而不是在后端使用多个SQL调用,并且(2)您可以控制{{1}中填充的内容},遗漏了什么。请注意,集合中只会填充您在Category中输入的内容。但是,如果您只是在addAttributeToSelect()之后,这应该不是问题。

首先,确保您是familiar with collections,然后为parent_id获取一个 CollectionFactory 单例,然后像这样填充它:

Magento\Catalog\Model\ResourceModel\Category\CollectionFactory

但是,强大的力量带来巨大的风险。上面的代码将没有任何错误纠正。如果存在逻辑数据库错误(例如,产品指向缺少的类别),则该类别将被从集合中省略,并且由程序员来确定并处理。此外,您还必须通过集合过滤器自行决定如何处理商店视图和活动/非活动类别。

直接数据库路由

好吧,除非您完全了解正在做什么,并且迫切需要性能,否则我不建议您使用此路线。

这将是疯狂的快速,但是存在各种各样的问题,例如依赖于基础数据存储和数据结构,更不用说您愿意(不太可能,公平地说)对基础进行将来的更新数据库结构,直接通过Magento升级或通过(讨厌的)第3方模块。更不用说SQL注入或XSS攻击的危险了。 (尽管如此,您应该始终牢记所有4种方法。

当您直接使用ObjectManager时,我认为您不会介意这些缺点,因此,尽管我也会给您这个选项。

基本的伪SQL是:

/** @var \Magento\Catalog\Model\ResourceModel\Category */
$collection = $this->_categoryCollectionFactory->create();

# Specifically select the parent_id attribute
$collection->addAttributeToSelect('parent_id');

# Only select categories with certain entity_ids (category ids)
$collection->addFieldToFilter('entity_id',['in' => $categoryIds])

# Iterate over results and print them out!
foreach ($collection as $category) {
    echo 'Parent Category ID: ',PHP_EOL;
}

首先,获取select parent_id from <name of catalog_category_entity table> where entity_id in (<sanitized,comma-separated list of category ids); 类的实例。您将使用它来获取\Magento\Framework\App\ResourceConnection的必要表名,以及获取数据库连接。然后,您应该清理数据,最后进行绑定并执行查询并获取数据。

catalog_category_entity

脚注

我认为您已经非常了解直接使用/** @var \Magento\Framework\App\Connection */ $connection = $this->_resourceConnection->getConnection(); # Get prefixed table name of catalog_category_entity $categoryEntityTableName = $this->_resourceConnection->getTableName('catalog_category_entity'); # Sanitize the $categoryIds array using a bit of overkill array_walk_recursive($categoryIds,function(&$value,$key){ $value = filter_var($value,FILTER_SANITIZE_NUMBER_INT); }); # Prepare a sql statement which fetches entity_id and parent_id $preparedStatement = $this->connection->prepare('select entity_id,parent_id from ' . $categoryEntityTableName . ' where entity_id in (' . implode(',',array_fill(0,sizeof($categoryIds),'?')) . ')'); # Bind sanitized $categoryIds array to statement and execute said statement in one single step $preparedStatement->execute($categoryIds); # fetch result as a key-value pair array of entity_id=>parent_id $parentIds = $preparedStatement->fetchAll(\PDO::FETCH_KEY_PAIR); # Iterate over results and print them out! foreach ($parentIds as $categoryId => $parentId) { echo 'Parent Category ID: ',(int)$parentId,PHP_EOL; } 的利弊,因此,我将为您省去讲课;-)。但是,为了将来参考,我还必须指出将来的读者,如果他们不知道如何获取ObjectManagerCategoryFactoryCategoryRepository或{ {1}}类,我强烈建议他们通过预期的Dependency Injection机制这样做。

本文链接:https://www.f2er.com/3134739.html

大家都在问