Namespace Declaration and Use Statements
Declaring Namespaces
<?php
// Every file should have one namespace declaration
// Must be the first statement (before any code)
namespace Vendor\Module\Model;
class Product
{
// This class is now Vendor\Module\Model\Product
}
Namespace Hierarchy
Vendor/
Module/
Controller/
Index/
Index.php -> Vendor\Module\Controller\Index\Index
Model/
Product.php -> Vendor\Module\Model\Product
ProductRepository.php -> Vendor\Module\Model\ProductRepository
Block/
Product/
View.php -> Vendor\Module\Block\Product\View
Api/
Data/
ProductInterface.php -> Vendor\Module\Api\Data\ProductInterface
etc/
di.xml
module.xml
Use Statements
<?php
namespace Vendor\Module\Service;
// Import classes with use statement
use Magento\Catalog\Model\Product;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Psr\Log\LoggerInterface;
class ProductPriceService
{
public function __construct(
private ProductRepositoryInterface $productRepo,
private LoggerInterface $logger
) {}
public function getPrice(int $productId): float
{
try {
$product = $this->productRepo->getById($productId);
return $product->getPrice();
} catch (NoSuchEntityException $e) {
$this->logger->error('Product not found: ' . $productId);
return 0.0;
}
}
}
// Alias long namespace names
use Magento\Framework\View\Element\Template as TemplateBlock;
use Vendor\Module\Helper\Data as ModuleHelper;
// Import functions (PHP 5.6+)
use function strlen;
use function array_map;
// Import constants (PHP 5.6+)
use const PHP_INT_MAX;
Using Classes Without Import
<?php
namespace Vendor\Module\Service;
// WITHOUT use statement - must use full namespace
$dateTime = new \DateTimeImmutable();
$arrayObject = new \ArrayObject();
// WITH use statement - cleaner
class OrderService
{
private \Magento\Sales\Model\OrderFactory $orderFactory;
public function __construct(
\Magento\Sales\Model\OrderFactory $orderFactory
) {
$this->orderFactory = $orderFactory;
}
}
// With use statement
class OrderService
{
public function __construct(
private \Magento\Sales\Model\OrderFactory $orderFactory
) {}
}
Key Takeaway
Namespaces organize code into logical groups. Use use statements to import classes. Every file should declare its namespace as the first statement. Follow the Vendor\Module\Layer\Class convention.
Namespace Resolution
Resolution Types
<?php
namespace Vendor\Module\Service;
// Absolute namespace (starts with \)
$now = new \DateTimeImmutable(); // Global namespace
$pdo = new \PDO('mysql:host=localhost');
// Relative namespace (no leading \)
// Looks in current namespace first, then global
$model = new \Magento\Framework\Model\AbstractModel();
// self:: refers to current class
self::someMethod(); // Calls method in this class
// parent:: refers to parent class
parent::someMethod(); // Calls parent's method
// static:: refers to the class the method is called on (late static binding)
class Base
{
public static function create(): static
{
return new static(); // Returns the calling class, not Base
}
}
class Child extends Base {}
$child = Child::create(); // Returns Child instance, not Base
Namespace Resolution Examples
<?php
namespace Vendor\Module\Helper;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\ScopeInterface;
class Data extends AbstractHelper
{
// Absolute: \DateTimeImmutable (global namespace)
// Relative: ScopeInterface (looks in current namespace first)
// Imported: AbstractHelper (via use statement)
public function formatDate(\DateTimeImmutable $date): string
{
return $date->format('Y-m-d');
}
public function getStoreConfig(string $path, int $storeId = null): ?string
{
return $this->scopeConfig->getValue(
$path,
ScopeInterface::SCOPE_STORE,
$storeId
);
}
}
Class vs Function vs Constant Resolution
<?php
namespace Vendor\Module\Service;
// Classes resolve with use statements
use Magento\Catalog\Model\Product;
// Functions use 'use function'
use function strlen;
use function array_map;
// Constants use 'use const'
use const PHP_INT_MAX;
use const Vendor\Module\Constants::MAX_PRODUCTS;
class ProductService
{
public function process(string $data): void
{
$length = strlen($data); // Uses imported function
$max = PHP_INT_MAX; // Uses imported constant
// Class from use statement
$product = new Product();
}
}
Namespaces in Magento Modules
app/code/Vendor/Module/
├── Block/
│ └── Product/
│ └── View.php # Vendor\Module\Block\Product\View
├── Controller/
│ ├── Index/
│ │ └── Index.php # Vendor\Module\Controller\Index\Index
│ └── Product/
│ └── View.php # Vendor\Module\Controller\Product\View
├── Helper/
│ └── Data.php # Vendor\Module\Helper\Data
├── Model/
│ ├── Product.php # Vendor\Module\Model\Product
│ ├── ResourceModel/
│ │ ├── Product.php # Vendor\Module\Model\ResourceModel\Product
│ │ └── Product/
│ │ └── Collection.php # Vendor\Module\Model\ResourceModel\Product\Collection
│ └── ProductRepository.php # Vendor\Module\Model\ProductRepository
├── Api/
│ └── Data/
│ └── ProductInterface.php # Vendor\Module\Api\Data\ProductInterface
├── Observer/
│ └── ProductSave.php # Vendor\Module\Observer\ProductSave
├── Plugin/
│ └── ProductPlugin.php # Vendor\Module\Plugin\ProductPlugin
├── etc/
│ ├── module.xml
│ ├── di.xml
│ └── events.xml
└── registration.php
Key Takeaway
Always use fully qualified names with a leading \ for global classes. Import classes with use statements for cleaner code. self:: refers to current class, static:: uses late static binding.
Magento Module Namespace Structure
Creating a Magento Module
<?php
// registration.php - registers the module
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
ComponentRegistrar::MODULE,
'Vendor_Module',
__DIR__
);
Namespace Convention
<?php
// Module namespace: Vendor_Module
// PHP namespace: Vendor\Module
// Layer -> Sub-namespace
namespace Vendor\Module\Model; // Model layer
namespace Vendor\Module\Block; // Block layer
namespace Vendor\Module\Controller; // Controller layer
namespace Vendor\Module\Helper; // Helper layer
namespace Vendor\Module\Observer; // Observer layer
namespace Vendor\Module\Plugin; // Plugin layer
namespace Vendor\Module\Service; // Service layer
namespace Vendor\Module\Api; // API layer
// Sub-layer convention
namespace Vendor\Module\Model\ResourceModel; // Resource models
namespace Vendor\Module\Model\ResourceModel\Product; // Specific resource model
namespace Vendor\Module\Model\ResourceModel\Product\Collection; // Collections
namespace Vendor\Module\Api\Data; // Data interfaces
Complete Module Example
<?php
// Model\Product.php
namespace Vendor\Module\Model;
use Magento\Framework\Model\AbstractModel;
use Vendor\Module\Model\ResourceModel\Product as ProductResource;
use Vendor\Module\Api\Data\ProductInterface;
class Product extends AbstractModel implements ProductInterface
{
protected function _construct()
{
$this->_init(ProductResource::class);
}
public function getName(): string
{
return $this->getData('name');
}
public function setName(string $name): self
{
return $this->setData('name', $name);
}
}
<?php
// Model\ResourceModel\Product.php
namespace Vendor\Module\Model\ResourceModel;
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
class Product extends AbstractDb
{
protected function _construct()
{
$this->_init('vendor_module_product', 'entity_id');
}
}
<?php
// Model\ResourceModel\Product\Collection.php
namespace Vendor\Module\Model\ResourceModel\Product;
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
use Vendor\Module\Model\Product;
use Vendor\Module\Model\ResourceModel\Product as ProductResource;
class Collection extends AbstractCollection
{
protected function _construct()
{
$this->_init(Product::class, ProductResource::class);
}
}
<?php
// Block\Product\View.php
namespace Vendor\Module\Block\Product;
use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;
use Vendor\Module\Model\ProductFactory;
class View extends Template
{
public function __construct(
Context $context,
private ProductFactory $productFactory,
array $data = []
) {
parent::__construct($context, $data);
}
public function getProduct(int $id): Product
{
return $this->productFactory->create()->load($id);
}
}
Namespace Best Practices
1. One class per file
2. Namespace must be first statement in file
3. Use statement should follow namespace declaration
4. Match directory structure to namespace structure
5. Vendor name should be unique (e.g., YourCompany, not generic names)
6. Module name should be PascalCase: Vendor_ModuleName
Key Takeaway
Magento follows strict namespace conventions: Vendor\Module\Layer\SubLayer. The directory structure mirrors the namespace structure. One class per file, namespace declared first, use statements imported.
Quiz
1. What must be the first statement in a PHP file that uses namespaces?
2. What does the \ (leading backslash) mean in namespace resolution?
3. What does the 'use' keyword do in PHP?
4. What is the Magento namespace convention for a module?
5. What does 'as' do in a use statement?
Flashcards
Question
What is a PHP namespace?
Click to reveal answer
Answer
A way to organize code into logical groups and prevent class name conflicts. Declared with namespace Vendor\Module\Model; as the first statement in a file.
Question
What does the use statement do?
Click to reveal answer
Answer
Imports a class, function, or constant so you can use its short name. Example: use Magento\Catalog\Model\Product; lets you write Product instead of the full path.
Question
What does a leading \ mean in namespace resolution?
Click to reveal answer
Answer
Absolute namespace from the global root. \DateTimeImmutable refers to the global class, not one in the current namespace.
Question
What is Magento's module namespace convention?
Click to reveal answer
Answer
Vendor\Module\Layer\Class. Example: Vendor\Module\Model\Product, Vendor\Module\Block\Product\View.
Question
What does 'use as' do?
Click to reveal answer
Answer
Creates an alias for an imported class. use Long\Name\Class as Short; lets you use Short instead of the full name.
Question
What does 'use function' do?
Click to reveal answer
Answer
Imports a function. use function strlen; lets you call strlen() without the global namespace prefix.
Question
What does self:: refer to?
Click to reveal answer
Answer
The current class. Used to call methods or access properties of the class where the code is written, not the calling class.
Question
What does static:: refer to?
Click to reveal answer
Answer
The class the method is called on (late static binding). Used in inheritance to refer to the child class, not the parent.
Revision Notes
Interview Tips
- • Explain the difference between absolute and relative namespace resolution
- • Know Magento's namespace convention (Vendor\Module\Layer\Class)
- • Describe when to use use statement vs full namespace path
- • Understand self:: vs static:: in inheritance
- • Be able to create a properly namespaced Magento module
Cheat Sheet
PHP Namespaces Cheat Sheet
Declaration:
namespace Vendor\Module\Model;
Import:
use Magento\Catalog\Model\Product;
use Long\Name\Class as Short;
use function strlen;
use const PHP_INT_MAX;
Resolution:
\ClassName - Absolute (global namespace)
ClassName - Relative (current then global)
self::method() - Current class
parent::method() - Parent class
static::method() - Called class (late binding)
Magento Convention:
Vendor\Module\Layer\Class
app/code/Vendor/Module/Layer/Class.php