The Bootstrap Process
Overview
HTTP Request → pub/index.php
↓
1. Error handling setup
2. Autoloader registration
3. ObjectManager creation
4. Area code initialization
5. Configuration loading
6. Application ready
Step 1: pub/index.php
<?php
// pub/index.php
use Magento\Framework\App\Bootstrap;
// 1. Error handling
require __DIR__ . '/../app/autoload.php';
// 2. Create ObjectManager via Bootstrap
$bootstrap = Bootstrap::create(
BP, // Base path (project root)
[
'mode' => 'developer', // or 'production'
]
);
// 3. Run application
$bootstrap->run(
new Magento\Framework\App\Http(
$bootstrap->getObjectManager()
)
);
Step 2: Autoloader
// app/autoload.php
require BP . '/vendor/autoload.php';
// Composer autoloader registers:
// - PSR-4 autoloading for all modules
// - Classmap for generated classes
// - Custom autoloaders for Magento framework
Step 3: ObjectManager Creation
// Magento\Framework\App\Bootstrap::create()
// 1. Load app/etc/env.php (environment config)
// 2. Load app/etc/config.php (module list)
// 3. Create ObjectManager with configuration
// 4. Register compiled configuration if available
// ObjectManager is the DI container that:
// - Resolves all dependencies
// - Manages shared/non-shared instances
// - Handles preferences (interface → implementation)
// - Generates factories, proxies on-demand
Step 4: Area Code
// Area code determines which context we're in
// Set by the entry point:
// Frontend: area code = 'frontend'
// Admin: area code = 'adminhtml'
// REST API: area code = 'api'
// Cron: area code = 'crontab'
$bootstrap = Bootstrap::create(BP, []);
$bootstrap->run($app);
// Inside Bootstrap::run(), area code is set:
// $this->state->setAreaCode('frontend');
// Area code affects:
// - Which di.xml files are loaded
// - Which plugins are active
// - Which observers are registered
// - Which layout handles are used
Step 5: Configuration Loading
1. app/etc/env.php (DB, cache, crypt)
2. app/etc/config.php (module list)
3. All module etc/module.xml (dependencies)
4. All module etc/di.xml (dependency injection)
5. etc/frontend/di.xml (area-specific DI)
6. Compiled config (var/di/global.php if exists)
7. ObjectManager resolves all dependencies
The entire configuration is loaded and merged before any application code runs.
ObjectManager Deep Dive
What ObjectManager Does
// ObjectManager is Magento's DI container
objectManager = Bootstrap::getObjectManager();
// Create any class with dependency resolution
$product = $objectManager->create(
\Magento\Catalog\Model\Product::class,
['data' => ['sku' => 'test']]
);
// Get shared instance (singleton)
$repository = $objectManager->get(
\Magento\Catalog\Api\ProductRepositoryInterface::class
);
// Shared vs create:
// get() → returns same instance every time (shared)
// create() → returns new instance every time
Compiled Configuration
# When you run setup:di:compile
bin/magento setup:di:compile
# Magento generates:
# 1. Factories for all injectable classes
# 2. Proxies for lazy loading
# 3. Interceptors for plugin system
# 4. Compiled DI config (var/di/global.php)
# Next request uses compiled config (faster)
# Development mode: no compilation (slower but dynamic)
ObjectManager Internals
// Simplified ObjectManager resolution:
1. Check compiled config (if available)
2. Check di.xml preferences (interface → implementation)
3. Resolve constructor arguments:
a. Type-hinted class/interface
b. Default values from di.xml <arguments>
c. Scalar values from di.xml
4. Create instance (shared or new)
5. Apply plugins (interceptors)
6. Return instance
// Cache: ObjectManager caches resolved definitions
// So the resolution process happens once per class
Why ObjectManager is Controversial
// BAD: Direct ObjectManager usage (anti-pattern)
$product = ObjectManager::getInstance()->get(Product::class);
// Hidden dependency, hard to test, not explicit
// GOOD: Constructor injection (preferred)
class ProductProcessor
{
public function __construct(
private ProductRepositoryInterface $productRepo // Explicit
) {}
}
ObjectManager exists to bootstrap the application. After bootstrap, use constructor injection. The ObjectManager is only used directly in very specific cases (factories, proxies).
Quiz
1. What is the first file executed in a Magento web request?
2. What does the area code determine?
3. What does bin/magento setup:di:compile generate?
Flashcards
Question
What is the web entry point?
Click to reveal answer
Answer
pub/index.php
Question
What does ObjectManager do?
Click to reveal answer
Answer
DI container — resolves dependencies, manages shared instances
Question
What is an area code?
Click to reveal answer
Answer
Context identifier (frontend, adminhtml, api, crontab) that determines active config
Question
What does setup:di:compile generate?
Click to reveal answer
Answer
Factories, proxies, interceptors, compiled DI config
Question
Shared vs create()?
Click to reveal answer
Answer
get() = shared instance (singleton), create() = new instance each time
Revision Notes
Key Takeaways
- 1. Bootstrap: pub/index.php → autoload → ObjectManager → area code → config → ready
- 2. ObjectManager resolves all dependencies via constructor injection
- 3. Area code determines which DI config, plugins, and observers are active
- 4. setup:di:compile generates factories, proxies, interceptors for production
- 5. Always use constructor injection, not direct ObjectManager usage
Interview Tips
- • Walk through the bootstrap process step by step
- • Explain why ObjectManager is controversial (anti-pattern when used directly)
- • Discuss how area code affects which modules and plugins are loaded
Cheat Sheet
Bootstrap Process:
1. pub/index.php (entry point)
2. autoload.php (Composer autoloader)
3. Bootstrap::create() → ObjectManager
4. Area code set (frontend/adminhtml/api/crontab)
5. Configuration loaded (env.php, config.php, di.xml)
6. Application runs
ObjectManager:
get() → shared instance (singleton)
create() → new instance each time
resolve() → compile dependency tree
setup:di:compile → factories + proxies + interceptors + compiled config