Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Controllers and actions

An action is a class that receives a request and returns a response. In Magento every URL has its own class with a single execute() method. The word "controller" here simply means a folder that holds related actions.

Where an action lives

The URL /hello/index/index leads to the module's Controller/Index/Index.php class. The file is created by hand.

app/code/Acme/Hello/
├── registration.php
├── Controller/
│   └── Index/
│       └── Index.php       new file
└── etc/
    ├── module.xml
    └── frontend/
        └── routes.xml

A simple action

// app/code/Acme/Hello/Controller/Index/Index.php
namespace Acme\Hello\Controller\Index;
 
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Controller\ResultInterface;
 
class Index implements HttpGetActionInterface
{
    public function __construct(private ResultFactory $resultFactory) {}
 
    public function execute(): ResultInterface
    {
        $result = $this->resultFactory->create(ResultFactory::TYPE_RAW);
        $result->setContents('Hello from the module!');
 
        return $result;
    }
}

Open http://shop.test/hello — the browser shows the line "Hello from the module!" without the shop design. The HttpGetActionInterface interface lets the action answer only GET requests; for form submissions use HttpPostActionInterface. Magento passes the ResultFactory object into the constructor itself — the dependency injection lesson explains how.

Result types

The execute() method returns a result object. The type is set by a ResultFactory constant:

ConstantWhat it returns
TYPE_RAWArbitrary text
TYPE_PAGEA shop page with the header and the footer
TYPE_JSONData in JSON format
TYPE_REDIRECTA redirect to another URL
TYPE_FORWARDHands the request to another action

A shop page

Replace the body of the execute() method:

$page = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
$page->getConfig()->getTitle()->set(__('Greeting'));
 
return $page;

The /hello URL now opens a regular shop page with the title "Greeting" and an empty middle. The layouts lesson shows how to fill it. The __() function makes a string translatable.

A JSON response and parameters

Create a second action — the Controller/Index/Status.php file:

// app/code/Acme/Hello/Controller/Index/Status.php
namespace Acme\Hello\Controller\Index;
 
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Controller\ResultInterface;
 
class Status implements HttpGetActionInterface
{
    public function __construct(
        private ResultFactory $resultFactory,
        private RequestInterface $request,
    ) {}
 
    public function execute(): ResultInterface
    {
        $id = (int) $this->request->getParam('id');
 
        return $this->resultFactory->create(ResultFactory::TYPE_JSON)
            ->setData(['status' => 'ok', 'id' => $id]);
    }
}

The URL /hello/index/status/id/5 returns {"status":"ok","id":5}. The getParam() method reads a parameter both from the URL path and from the query string; the second argument is a default value.

Redirect

return $this->resultFactory->create(ResultFactory::TYPE_REDIRECT)->setPath('hello');

The visitor lands on the /hello page. setPath() takes a path in the same form as getUrl().

Common mistake

The page returns 404 although the class is written. Check three things: the namespace matches the file path, the folder is called Controller in the singular, and the letter case of the folder and file names is exactly the same as in the class. On Windows a case mistake goes unnoticed, but on a Linux server the file will not be found.

Thanks for reading!

Donate to the site — we work hard for you.