How to create a controller and its actions in Magento2

This tutorial is the 2nd in a long series of magento2 tutorial. It will be updated little by little with the evolutions of the platform. You will now learn how to create your controller and its actions under Magento2 . If you do not know magento (v1) it is not a problem, I will talk about it but it is not necessary to know the magento 1.x platform to master this tutorial on magento2 .

In this tutorials, you will create an address book management module for magento2 with an administration interface, a front desk, access to the database and everything else.

First create the folders of your module

Go to the /app/code folder from the root of your magento directory. Then create a folder "Pfay" and in another folder "Contacts".
Then create a folder "Controller" and another directory "etc" in the "Contacts" folder.

The namespace:
Your module is located in the Pfay namespace. It is in this folder that you will "store" the modules you will create.
Be careful, you should NEVER modify the "core" files of magento2, ie the folder /app/code/Magento, otherwise if you have try to update the platform, you'll have big problems.

Declaring its module under magento2

Now that you have created the folders of your module, you must "declare" its module to magento. To do this, we will create the module.xml file in the /etc folder of our module that look like this:

<?xml version="1.0"?>
<config xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Pfay_Contacts" setup_version="2.0.0">
            <module name="Magento_Cms"/>

we will create the file "registration file" too. Go to app/code/Pfay/Contacts, and create the registration.php like this :


When you launch the following command :

php bin/magento setup:upgrade

You will see that this line

'Pfay_Contacts' => 1

is inserted in the file app/etc/config.php. This allows you to know that your module is active. For those who know magento (1.X), you have to know that under magento2 you don't need to declare your module in /app/etc/module/ anymore, the templates in design, etc... now with magento2 t everything that concerns your module is in its folder. In magento2 you have two concepts: "strong dependency" et "weak dependency".

The module dependencies in magento2

Strong dependency of a module
resume : Magento2 is not working if the dependencies are not present.
The module contains logic code of other modules, class, statics methods, a static property of a class, an interface, etc....What you have to remind is that it the dependecy module is not there...404 !

Weak dependency of a module
resume : Magento2 still works if the dependencies are not there
The module still work if the dependencies are not here. Generely, it extends the functions of others modules, it check the availability of the dependency first. and if it's not present, it doest throw an handle it.

Creation of the controller

In the folder app/code/Pfay/Contacts/Controller, create a folder Test and in the following create the Index.php file like the following :

namespace Pfay\Contacts\Controller\Test;
class Index extends \Magento\Framework\App\Action\Action
    public function execute()
        die('test index');

Be carreful, you will notice that when we define the namespace of the file, there is no \ at the beginning while there is one in the extends....
In short, here we create an Index class which is actually a magento2 Action . In fact, in magento2, there is no more controllers. now you create on file by action. Theses actions extends the core class \Magento\Framework\App\Action\Action and must have a function execute(). When you were grouping actions in one controller in magento 1.x, now you will group actions classes in a folder.

Create a route to access our controller

In order to access our module via the frontend, you must create the route for the frontend of our module. Here we want to access our module via url www.magento2.lan/contacts/. We wukk create a "frontend" folder in the "etc" folder, then insert our "routes.xml" file.

The file routes.xml must be like that :

<?xml version="1.0"?>
<config xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="contacts" frontName="contacts">
            <module name="Pfay_Contacts" />

We use the "standard" router that allows access to the frontend portion of our magento2 module! And we add the route with the id "contacts" to identify it and the frontName "contacts" which is the key url by which you will access your module on the frontend. In this route, we then define our module element with the name attribute that contains the "namespace" + "name of our module".

For your information, you should also use a file of type routes.xml to create a path in the backoffice.

Small point on the organization of controllers

When stating from the root of the module, we have our file
We will tell in the next steps on this tutorial that we are on the Action Index, of our controller Test. and we will access it by going to the url


The action named index is the action that magento will take by default if you don't specify the action in the url. We can access it via :


On these two urls, you will se "test index" diplay.

If you want nother action View for exemple, we can create another file View.php in the Test folder wich contains :

namespace Pfay\Contacts\Controller\Test;
class View extends \Magento\Framework\App\Action\Action
    public function execute()
        die('test index');

Si vous allez sur l'url :


You will see displayed "test view"

Wtf ! Why it's not diplaying for me ? some solutions...

- it doesn't work ? empty the cache
System > Cache management in the backoffice and disable all the cache

- display error messages :
rename local.xml.sample in local.xml in the folder pub/errors/
and be sure that in /bootstrap.php you have this two lined uncommented :

ini_set('display_errors', 1);

-"Setup version for module 'Pfay_Contacts' is not specified"
the registration.php file of your module is missing

-"Please upgrade your database: Run "bin/magento setup:upgrade" from the Magento root directory"
launch theses command :

php bin/magento setup:upgrade

And recompile :

php bin/magento setup:di:compile
Compilation was started.
Interception cache generation... 7/7 [============================] 100% 34 secs 246.0 MiBBMiB

The compilation is not active in "developer mode", these manipulation are not to do when you are in a production environement.
To enable the developer mode (and not to have to recompile at every modifications...;) ) here is how to do :

php bin/magento deploy:mode:set developer
Enabled developer mode.

You have created the first router on magento2 with success. Congralutations!

The is not working at home ? You can Get the source code of this tutorial by clicking on the link in the back of this tutorial (premium members only).

See you on the next lesson ;)
Available documents for this article :
Books that can help you :
  • Livre Magento 2 Developer's Guide by Branko
  • Livre Mastering Magento2 Second Edition
  • Livre Magento 2 Cookbook
Questions about this lesson
No questions for this lesson. Be the first !

You must be logged in to ask for help on a lesson.