41

It's pretty basic, but I can’t find a working example on Stackexchange or google. I want to load a product from a helper or block. I already tried some things like:

$objectManager = \Magento\Framework\App\ObjectManager::getInstance(); 

$product = $objectManager->create('\Magento\Catalog\Api\Data\ProductInterface');

$product->get('<SKU>');

$product->getName();

This returns nothing. I also tried loading any available models and API’s, but nothing seems to work with SKU’s.

7 Answers 7

87

The correct way, according to Magento 2 service contracts, is using repositories:

$product = $this->productRepositoryInterface->get($sku);

Use Magento\Catalog\Api\ProductRepositoryInterface to get it in your constructor.

Full example:

...
private $productRepository; 
...
public function __construct(
    ...
    \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
    ...
) {
    ...
    $this->productRepository = $productRepository;
    ...
}

public function loadMyProduct($sku)
{
    return $this->productRepository->get($sku);
}
...

Note:

If the product does not exists, this method triggers a NoSuchEntityException error as it would be in the best Magento2 practice.

So, if you need to handle somehow, wrap it in a try/catch block.

15
  • 9
    This method gives an error when no product is found. So for checking if an product exists, It seems @fschmengler's solution might be the better way to go. Commented Apr 20, 2016 at 11:00
  • 1
    can you pls add more details about Use Magento\Catalog\Api\ProductRepositoryInterface to get it in your constructor.? What shall I do? Thanks a lot
    – davideghz
    Commented Dec 16, 2016 at 17:17
  • See my updated post Commented Dec 16, 2016 at 17:25
  • The actual proper Magento 2 way to use service contracts is more complicated. Repository->get() is still a model call which shouldn't be used. The correct way is to use repository->getList() with SearchCriteriaBuilder. See my answer on Orders (pretty much the same method): magento.stackexchange.com/questions/140374/…
    – Jacques
    Commented Apr 10, 2017 at 10:08
  • 1
    @JaccoAmersfoort, I confirm "get" is the right way. In your example it has been suggested because "get" in order repository requires "order id" and that user was looking for "increment id". In that case a getList is the best option, but if you can use "get" you should use it. Commented Apr 10, 2017 at 10:57
33

Instead of using the object manager directly, inject the ProductFactory:

public function __construct(\Magento\Catalog\Model\ProductFactory $productFactory)
{
    $this->productFactory = $productFactory;
}

Then use it like this:

$product = $this->productFactory->create();
$product->loadByAttribute('sku', $sku);

or to do a full load (the above loads it using a collection):

$product = $this->productFactory->create();
$product->load($product->getIdBySku($sku));
8
  • 7
    Actually while this is still working, using load() and collections is the "Magento 1" way, better use the repository as suggested by @RiccardoT. Commented Apr 17, 2016 at 20:46
  • 1
    Also, your method will return a Product model, whilst using the Repository will give you a Product data model (Api/Data/Product), which is a Product model converted into a dumbed-down DTO. Something to consider, as they're quite different.
    – nevvermind
    Commented Apr 18, 2016 at 0:02
  • @FabianSchmengler: Tried using $product = $this->productFactory->create(); $product->load($product->getIdBySku($sku)); $product->getThumbnailUrl() to display product thumbnail image, but its not working. Commented Jan 31, 2018 at 7:24
  • 1
    @FabianSchmengler yes recommendation of Repository is good as @RiccardoT answer. but what if i entered wrong sku then it will break whole operation & throw exception, so in this case we must have to depend on productFactory
    – Himanshu
    Commented Nov 5, 2018 at 6:20
  • 1
    @FabianSchmengler have tried to catch the exception but it is still breaking the same.
    – Himanshu
    Commented Nov 6, 2018 at 5:21
14

I like @phoenix128-riccardot 's answer, but would add an exception, just in case the product does not exist:

try {
    $product = $this->productRepositoryInterface->get($sku);
} catch (\Magento\Framework\Exception\NoSuchEntityException $e){
    // insert your error handling here
}

I was not able to add it as a comment (too low reputation), sorry.

9

You can try that

$objectManager = \Magento\Framework\App\ObjectManager::getInstance(); 

$productRepository = $objectManager->get('\Magento\Catalog\Model\ProductRepository');
$productObj = $productRepository->get('<SKU>');

echo $productObj->getId();
5

Try this:

/** @var \Magento\Catalog\Model\ProductFactory $productFactory */
$product = $productFactory->create();
$product->loadByAttribute('sku', 'my sku');

// $product->load($product->getId()); // may need to do this too,
// see \Magento\Framework\Api\AttributeValueFactory\AbstractModel::loadByAttribute
1
  • I need to get the product_id from sku (column of csv) during csv import and save only the product_id..How to achieve?
    – Sushivam
    Commented Aug 25, 2016 at 9:45
2

Using Dependency Injection (DI)

Here is the example code to get the product information by product Id and SKU in Magento 2 using dependency injection.

In this, we might need to inject the object of the \Magento\Catalog\Model\ProductRepository class in the constructor of our module’s block class and access it from the view ( .phtml ) file.

Sample File Path: app/code/YourCompanyName/YourModuleName/Block/YourCustomBlock.php

<?php
namespace YourCompanyName\YourModuleName\Block;

class YourCustomBlock extends \Magento\Framework\View\Element\Template
{ 
    protected $_productRepository;

    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context, 
        \Magento\Catalog\Model\ProductRepository $productRepository,
        array $data = []
    ) {
        $this->_productRepository = $productRepository;
        parent::__construct($context, $data);
    }

    public function getProductById($id) {
        return $this->_productRepository->getById($id);
    }

    public function getProductBySku($sku) {
        return $this->_productRepository->get($sku);
    }
}

Now, we can use the functions in our view (.phtml) file as follows.

// get product by id
$product = $block->getProductById(15);

// get product by sku
$product = $block->getProductBySku('MT12');

echo $product->getEntityId() . '<br>';
echo $product->getName() . '<br>';
echo $product->getSKU() . '<br>';
echo $product->getPrice() . '<br>';
echo $product->getSpecialPrice() . '<br>';
echo $product->getTypeId() . '<br>';
echo $product->getProductUrl() . '<br>';

Using Object Manager

Here is the example code to get the product information by product id and SKU in Magento 2 using object manager.

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();

$productRepository = $objectManager->get('\Magento\Catalog\Model\ProductRepository');

// get product by product id 
$product = $productRepository->getById(15);

// get product by product sku 
$product = $productRepository->get('MT12');

echo $product->getEntityId() . '<br>';
echo $product->getName() . '<br>';
echo $product->getSKU() . '<br>';
echo $product->getPrice() . '<br>';
echo $product->getSpecialPrice() . '<br>';
echo $product->getTypeId() . '<br>';
echo $product->getProductUrl() . '<br>';
-2
<?php
use Magento\Framework\App\Bootstrap;
require __DIR__ . '/app/bootstrap.php';
$bootstrap = Bootstrap::create(BP, $_SERVER);
$obj = $bootstrap->getObjectManager();
$state = $obj->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');


$sku ='24-MB01';
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$productObject = $objectManager->get('Magento\Catalog\Model\Product');
$product = $productObject->loadByAttribute('sku', $sku);
echo $product->getName();

?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.