Magento 2 Request Flow In Depth

So far we have seen about the routers of magento but let’s understand the request flow by creating a simple controller, you can consider any existing controller and traverse through following steps by applying echo or var_dump. Lets start with our magento entry file

Index.php #39 
Code:-
/** @var \Magento\Framework\App\Http $app */
$app = $bootstrap->createApplication('Magento\Framework\App\Http');
$bootstrap->run($app);

Let us enter to our run function which is taking $app as parameter ($app is an instance of \Magento\Framework\App\Http). In bootstrap.php we have run function which launches the application.

class: \Magento\Framework\App\Http
public function run(AppInterface $application)
    {
        try {
            try {
                \Magento\Framework\Profiler::start('magento');
                $this->initErrorHandler();
                $this->initObjectManager();
                $this->assertMaintenance();
                $this->assertInstalled();
                $response = $application->launch();
                $response->sendResponse();
                \Magento\Framework\Profiler::stop('magento');
            } catch (\Exception $e) {
                \Magento\Framework\Profiler::stop('magento');
                if (!$application->catchException($this, $e)) {
                    throw $e;
                }
            }
        } catch (\Exception $e) {
            $this->terminate($e);
        }
    }

It time to go now to launch function in Magento\Framework\App\Http and check the code is calling dispatch method of frontcontroller, which is then calling match function of routers and as per our previous post we know our request will go to base router.

class: Magento\Framework\App\Http
$result = $frontController->dispatch($this->_request);

So we will be looking into Magento\Framework\App\Router\Base.php for match function, while looking closely to match function we can see it calls to matchAction and return its output.

class: Magento\Framework\App\Router\Base
public function match(\Magento\Framework\App\RequestInterface $request)
    {
        $params = $this->parseRequest($request);

        return $this->matchAction($request, $params);
    }

And here is the code of matchAction that we need to discuss:-

$actionInstance = $this->actionFactory->create($actionClassName);

$this->ActionFactory is an instance of Magento\Framework\App\ActionFactory and if we will look in create function, we have call to object manager which we know is responsible for creating instances.

class: Magento\Framework\App\ActionFactory
    public function create($actionName)
    {
…
        return $this->_objectManager->create($actionName);
    }
Now let’s see how objectmanager create an instance of every parameter in contructor

i.e, dependency injection in constructor.

Above $this->_objectManager is an instance of Magento\Framework\ObjectManager\ObjectManager. Here you can see the create function which is calling another create function:-

class: Magento\Framework\ObjectManager\ObjectManager
public function create($type, array $arguments = [])
    {
        $type = ltrim($type, '\\');
        //var_dump(get_class($this->_factory)); 
        return $this->_factory->create($this->_config->getPreference($type), $arguments);
    }


$this->_factory
is an object of Magento\Framework\ObjectManager\Factory\Dynamic\Developer class. Basically we have two factory class of object manager one is for production mode and another for development. If we were in producttion mode then $this->_factory will be an instance of Magento\Framework\ObjectManager\Factory\Dynamic\Production

In Developer .php we have create function which is getting the constructor parameter using line

$parameters = $this->definitions->getParameters($type);

$this->definition is an instance of Magento\Framework\ObjectManager\Definition\Runtime
And here in getParameters function we can see that parameters of constructor are being fetched one by one.

class: Magento\Framework\ObjectManager\Definition\Runtime
public function getParameters($className)
    {
        if (!array_key_exists($className, $this->_definitions)) {
            $this->_definitions[$className] = $this->_reader->getConstructor($className);
        }
        return $this->_definitions[$className];
    }

Going back to create function of Magento\Framework\ObjectManager\Factory\Dynamic\Developer, we have return statement as return $this->createObject($type, $args);. Here
$type = classname
$args = list of partameters

Now $this->createObject is an instance of Magento\Framework\ObjectManager\Factory\AbstractFactory

And here you can clearly see that objects are created in below function

class: Magento\Framework\ObjectManager\Factory\AbstractFactory
createObject($type, $args)
    {
        return new $type(...array_values($args));
    }

Leave a Comment.