Introduction
Today, I will guide how to get product different way.
In Magento 2 development, retrieving product information by ID is a fundamental operation that can be accomplished through various methods. Each approach has its own advantages and use cases.
This comprehensive guide explores seven different methods to fetch product data, helping developers choose the most appropriate approach for their specific requirements.
Overview of Methods
Here, I will show 7 different methods for get product data by product ID. Let’s explore each methods.
1. Repository Pattern (Recommended)
The Repository Pattern is Magento 2’s recommended approach for product operations. It provides a clean, standardized interface for product management while maintaining proper dependency injection and ensuring consistent behavior across the application.
<?php
/**
* Copyright © 2025 All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Vendor\Module\Block\ProductLoad;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Catalog\Api\ProductRepositoryInterface;
class RepositoryMethod extends \Magento\Framework\View\Element\Template
{
/**
* @var ProductRepositoryInterface
*/
private $productRepository;
/**
* Constructor
*
* @param \Magento\Framework\View\Element\Template\Context $context
* @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
ProductRepositoryInterface $productRepository,
array $data = []
) {
parent::__construct($context, $data);
$this->productRepository = $productRepository;
}
/**
* Get product by ID using Repository Pattern
*
* @param int $productId
* @return \Magento\Catalog\Api\Data\ProductInterface
* @throws NoSuchEntityException
*/
public function getProductById($productId)
{
try {
return $this->productRepository->getById($productId);
} catch (NoSuchEntityException $e) {
throw new NoSuchEntityException(
__('The product with ID "%1" does not exist.', $productId)
);
}
}
}
Pros
- Clean and standardized interface
- Proper dependency injection
- Follows Magento best practices
- Consistent behavior
- Built-in caching mechanism
- Supports API integration
- Proper error handling
- Extensible through plugins
Cons
- Slightly more verbose implementation
- Learning curve for new developers
- May be overkill for simple operations
- Additional overhead for simple queries
- Requires proper service contract implementation
- More complex for custom attributes
- Limited direct database access
- Stricter type handling
2. Factory Method
The Factory Method creates new instances of product models, useful when you need a fresh product object without loading data from the database.
<?php
/**
* Copyright © 2025 All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Vendor\Module\Block\ProductLoad;
use Magento\Catalog\Model\ProductFactory;
use Magento\Framework\Exception\LocalizedException;
class FactoryMethod extends \Magento\Framework\View\Element\Template
{
/**
* @var ProductFactory
*/
private $productFactory;
/**
* Constructor
*
* @param \Magento\Framework\View\Element\Template\Context $context
* @param \Magento\Catalog\Model\ProductFactory $productFactory
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
ProductFactory $productFactory,
array $data = []
) {
parent::__construct($context, $data);
$this->productFactory = $productFactory;
}
/**
* Get product by ID using Factory Method
*
* @param int $productId
* @return \Magento\Catalog\Model\Product
* @throws LocalizedException
*/
public function getProductById($productId)
{
try {
$product = $this->productFactory->create()->load($productId);
if (!$product->getId()) {
throw new LocalizedException(__('Product not found'));
}
return $product;
} catch (\Exception $e) {
throw new LocalizedException(
__('Error loading product: %1', $e->getMessage())
);
}
}
}
Pros
- Creates fresh instances
- Memory efficient
- Flexible object creation
- Good for bulk operations
- Simple implementation
- Direct model access
- Supports custom initialization
- Good for temporary objects
Cons
- No built-in caching
- Manual dependency management
- Can lead to resource overhead
- Less standardized
- No built-in validation
- Potential memory leaks
- Limited API support
- Manual error handling
3. Object Manager (Not Recommended for Production)
While not recommended for production use, the Object Manager can be used for quick prototyping or testing.
<?php
$productId = 4;
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$product = $objectManager->get(\Magento\Catalog\Model\Product::class)->load($productId);
Pros
- Quick implementation
- Easy debugging
- Flexible object creation
- Direct access to services
- Simple syntax
- No dependency injection needed
- Fast prototyping
- Easy testing
Cons
- Not recommended for production
- Poor dependency management
- Hard to maintain
- Poor testability
- Performance overhead
- Security concerns
- Difficult to track dependencies
4. Model Method
The Model Method provides direct access to product data using Magento’s Model classes.
<?php
/**
* Copyright © 2025 All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Vendor\Module\Block\ProductLoad;
use Magento\Catalog\Model\Product;
use Magento\Framework\Exception\LocalizedException;
class ModelMethod extends \Magento\Framework\View\Element\Template
{
/**
* @var Product
*/
private $product;
/**
* Constructor
*
* @param \Magento\Framework\View\Element\Template\Context $context
* @param \Magento\Catalog\Model\Product $product
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
Product $product,
array $data = []
) {
parent::__construct($context, $data);
$this->product = $product;
}
/**
* Get product by ID using Model Method
*
* @param int $productId
* @return Product
* @throws LocalizedException
*/
public function getProductById($productId)
{
try {
$product = $this->product->load($productId);
if (!$product->getId()) {
throw new LocalizedException(__('Product not found'));
}
return $product;
} catch (\Exception $e) {
throw new LocalizedException(
__('Error loading product: %1', $e->getMessage())
);
}
}
}
Pros
- Simple implementation
- Direct data access
- Familiar pattern
- Good for simple operations
- Easy to extend
- Low learning curve
- Flexible attribute handling
- Quick development
Cons
- No built-in caching
- Resource intensive
- Poor separation of concerns
- Limited validation
- Not API friendly
- Potential performance issues
- Less maintainable
- Manual error handling
5. Resource Model Method
The Resource Model Method provides low-level database access for product data retrieval.
<?php
/**
* Copyright © 2025 All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Vendor\Module\Block\ProductLoad;
use Magento\Catalog\Model\ResourceModel\Product as ProductResource;
use Magento\Catalog\Model\Product;
use Magento\Framework\Exception\LocalizedException;
class ResourceModelMethod extends \Magento\Framework\View\Element\Template
{
/**
* @var ProductResource
*/
private $productResource;
/**
* @var Product
*/
private $product;
/**
* Constructor function
*
* @param \Magento\Framework\View\Element\Template\Context $context
* @param \Magento\Catalog\Model\ResourceModel\Product $productResource
* @param \Magento\Catalog\Model\Product $product
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
ProductResource $productResource,
Product $product,
array $data = []
) {
parent::__construct($context, $data);
$this->productResource = $productResource;
$this->product = $product;
}
/**
* Get product by ID using Resource Model
*
* @param int $productId
* @return Product
* @throws LocalizedException
*/
public function getProductById($productId)
{
try {
$product = $this->product;
$this->productResource->load($product, $productId);
if (!$product->getId()) {
throw new LocalizedException(__('Product not found'));
}
return $product;
} catch (\Exception $e) {
throw new LocalizedException(
__('Error loading product: %1', $e->getMessage())
);
}
}
}
Pros
- Low-level database access
- High performance
- Direct SQL queries
- Custom query support
- Efficient for bulk operations
- Fine-grained control
- Database optimization
- Transaction support
Cons
- Complex implementation
- No built-in caching
- Requires SQL knowledge
- Hard to maintain
- Poor abstraction
- Limited API support
- Security risks
- Database coupling
6. SearchCriteria Method
The SearchCriteria Method allows for flexible product searching with complex filtering options.
<?php
/**
* Copyright © 2025 All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Vendor\Module\Block\ProductLoad;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\Exception\LocalizedException;
class SearchCriteriaMethod extends \Magento\Framework\View\Element\Template
{
/**
* @var SearchCriteriaBuilder
*/
private $searchCriteriaBuilder;
/**
* @var ProductRepositoryInterface
*/
private $productRepository;
/**
* Constructor function
*
* @param \Magento\Framework\View\Element\Template\Context $context
* @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
* @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
SearchCriteriaBuilder $searchCriteriaBuilder,
ProductRepositoryInterface $productRepository,
array $data = []
) {
parent::__construct($context, $data);
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->productRepository = $productRepository;
}
/**
* Get product by ID using SearchCriteria
*
* @param int $productId
* @return \Magento\Catalog\Api\Data\ProductInterface
* @throws LocalizedException
*/
public function getProductById($productId)
{
try {
$searchCriteria = $this->searchCriteriaBuilder
->addFilter('entity_id', $productId, 'eq')
->create();
$products = $this->productRepository->getList($searchCriteria)->getItems();
if (empty($products)) {
throw new LocalizedException(__('Product not found'));
}
return reset($products);
} catch (\Exception $e) {
throw new LocalizedException(
__('Error searching for product: %1', $e->getMessage())
);
}
}
}
Pros
- Flexible filtering
- Complex search support
- API compatible
- Extensible filters
- Pagination support
- Sorting capabilities
- Multiple condition support
- Clean interface
Cons
- Performance overhead
- Complex for simple queries
- Learning curve
- Resource intensive
- Query complexity
- Memory usage
- Verbose implementation
- Limited direct access
7. Collection Method
The Collection Method is useful when working with multiple products or requiring additional filtering capabilities.
<?php
/**
* Copyright © 2025 All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Vendor\Module\Block\ProductLoad;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Framework\Exception\LocalizedException;
class CollectionMethod extends \Magento\Framework\View\Element\Template
{
/**
* @var ProductRepositoryInterface
*/
private $productRepository;
/**
* Constructor
*
* @param \Magento\Framework\View\Element\Template\Context $context
* @param \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $collectionFactory
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
CollectionFactory $collectionFactory,
array $data = []
) {
parent::__construct($context, $data);
$this->collectionFactory = $collectionFactory;
}
/**
* Get product by ID using Collection Method
*
* @param int $productId
* @return \Magento\Catalog\Model\Product
* @throws LocalizedException
*/
public function getProductById($productId)
{
try {
$collection = $this->collectionFactory->create();
$collection->addFieldToFilter('entity_id', $productId);
$product = $collection->getFirstItem();
if (!$product->getId()) {
throw new LocalizedException(__('Product not found'));
}
return $product;
} catch (\Exception $e) {
throw new LocalizedException(
__('Error loading product: %1', $e->getMessage())
);
}
}
}
Pros
- Efficient for multiple products
- Built-in filtering
- Memory efficient
- Batch processing
- Easy to extend
- SQL optimization
- Flexible queries
- Good for reports
Cons
- Resource intensive
- Complex queries
- Memory overhead for large sets
- No built-in caching
- Performance impact
- Limited API support
- Query optimization needed
- Manual error handling
Get Product Data in phtml file
Here, we are get product data by ID using repository method our phtml file.
<?php
/** @var \Vendor\Module\Block\ProductLoad\RepositoryMethod $block */
$productId = 1;
$product = $block->getProductById($productId);
?>
<div class="using-repository get-product">
<h2><?= $block->escapeHtml(__('Repository Pattern Method')) ?></h2>
<?php if ($product): ?>
<div class="product-details">
<p><strong><?= $block->escapeHtml(__('ID')) ?>:</strong> <?= $block->escapeHtml($product->getId());?></p>
<p><strong><?= $block->escapeHtml(__('Name')) ?>:</strong> <?= $block->escapeHtml($product->getName());?></p>
<p><strong><?= $block->escapeHtml(__('SKU')) ?>:</strong> <?= $block->escapeHtml($product->getSku());?></p>
</div>
<?php endif; ?>
</div>
</div>

Best Practice Recommendations
Performance Considerations
Security Best Practices
Conclusion
While Magento 2 offers multiple methods to retrieve products by ID, the Repository Pattern remains the recommended approach for most use cases.
It provides the best balance of functionality, maintainability, and adherence to Magento best practices. However, understanding all available methods helps developers make informed decisions based on specific requirements.
Key Takeaways:
- Repository Pattern is the recommended approach for most cases
- Each method has specific use cases and trade-offs
- Consider performance implications when choosing a method
- Proper error handling is crucial
- Follow Magento best practices and coding standards
- Cache frequently accessed data
- Use dependency injection
- Implement proper security measures
FAQs
Which method is best for high-performance requirements?
The Resource Model method typically offers the best performance for specific use cases, but the Repository Pattern with proper caching is recommended for general use.
Should I ever use the Object Manager directly?
No, the Object Manager should not be used directly in production code. Use dependency injection instead.
How do I handle custom product attributes?
Custom attributes are best handled through the Repository Pattern or Collection Method, with proper extension attributes configuration.
Which method is best for API integration?
The Repository Pattern is ideal for API integration as it provides a consistent interface and proper service contracts.
How can I improve performance when loading multiple products?
Use collections with specific field filters, implement proper indexing, and utilize caching mechanisms. Avoid loading full product objects when only specific attributes are needed.
What's the best way to handle product caching?
Implement Magento’s built-in caching mechanisms, use the Repository Pattern’s native caching, and consider using full-page cache for frontend displays. For custom implementations, utilize Redis or other caching solutions.
How should I handle product loading in custom API endpoints?
Use the Repository Pattern with proper service contracts. This ensures consistency across the application and maintains proper API interfaces.
What's the recommended approach for handling product updates?
Use the Repository Pattern’s save method, which ensures proper event dispatching, indexing, and cache invalidation.
Can I mix different methods in the same module?
While possible, it’s recommended to maintain consistency by using the Repository Pattern throughout your module. This ensures better maintainability and consistent behavior.
How do I handle product variations and configurable products?
Use the Repository Pattern with proper type handling and the ConfigurableProduct module’s specific interfaces for managing product variations.
What's the impact of each method on memory usage?
Collections and full product loads can be memory-intensive. Use repositories with specific attributes when possible, and implement batch processing for large datasets.
How do I ensure proper dependency injection when working with products?
Use constructor injection with proper interface types, avoid the Object Manager, and follow Magento’s dependency inversion principles.
What's the best practice for loading products in frontend blocks?
Use the Repository Pattern with proper caching mechanisms, and implement lazy loading when appropriate to improve page load performance.
How do I handle product loading in different store views?
Use the Repository Pattern with proper store context, ensuring the store ID is set correctly before loading products.
How can I debug product loading issues?
Enable logging, use Magento’s debug tools, implement proper exception handling, and utilize development mode for detailed error messages.
What's the best way to handle product attributes in GraphQL?
Use the Repository Pattern with proper schema configuration and resolver implementation for optimal GraphQL integration.
How do I optimize product loading for search results?
Use the SearchCriteria method with proper filters and pagination, implement elasticsearch for better performance, and cache results when appropriate.
Thank you for reading this article.