26

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.

51

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.

  • 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. – Dennis van Schaik Apr 20 '16 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 Dec 16 '16 at 17:17
  • See my updated post – Phoenix128_RiccardoT Dec 16 '16 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 Apr 10 '17 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. – Phoenix128_RiccardoT Apr 10 '17 at 10:57
26

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));
  • 7
    Actually while this is still working, using load() and collections is the "Magento 1" way, better use the repository as suggested by @RiccardoT. – Fabian Schmengler Apr 17 '16 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 Apr 18 '16 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. – Slimshadddyyy Jan 31 '18 at 7:24
  • @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 Nov 5 '18 at 6:20
  • @Himanshu catch the exception. And if you need a fresh product instance in that case, you can still create it using the factory – Fabian Schmengler Nov 5 '18 at 17:00
6

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.

3

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
  • 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 Aug 25 '16 at 9:45
3

You can try that

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

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

echo $productObj->getId();
0

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>';
-3
<?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, privacy policy and cookie policy

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