How to retrieve the root dir of the project and other container parameters using a Service in Symfony 4

After upgrading a project from Symfony 3 to Symfony 4, i discovered how unintuitive it was to get parameters from the config.yml or parameters.yml as we used to do in Symfony 4. In the new version, parameters are handled in the services.yaml file or in the .env file of the project. Normally, you can live with that, just writing the new parameters to the env file and retrieving them with the getenv function of PHP. However, a lot of exceptions were thrown in the legacy code due to the unavailability of the container inside a controller that extends the AbstractController class instead of the classic Controller. This forced me to research a way to retrieve the project root directory using the framework and here i am sharing the result with you.

In this article, i'll explain you how to retrieve the root directory path of your Symfony 4 project and other parameters available in the service container.

1. Create helper class

We will retrieve parameters of the container interface through a helper that we will register as a service. The helper class is the following one, create the ContainerParametersHelper.php file in the /yourapp/src/Service directory with the following content:

<?php

// app/src/Service/ContainerParametersHelper.php

namespace App\Service;

use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;

class ContainerParametersHelper {
    
    private $params;
     
    public function __construct(ParameterBagInterface $params)
    {
        $this->params = $params;
    }

    /**
     * This method returns the root directory of your Symfony 4 project.
     * 
     * e.g "/var/www/vhosts/myapplication"
     * 
     * @return type
     */
    public function getApplicationRootDir(){
        return $this->params->get('kernel.project_dir');
    }

    /**
     * This method returns the value of the defined parameter.
     * 
     * @return type
     */
    public function getParameter($parameterName){
        return $this->params->get($parameterName);
    }
}

2. Register service

In case that you have the autowire feature enabled in your project (enabled by default in new symfony web projects), just creating the file in the specified directory will be enough and you can skip this step. You can verify if your project has the autowire feature enabled, opening the services.yaml file of your project and checking if the options autowire and autoconfigure are set to true:

# app/config/services.yaml
services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

If it looks like this, you are ready to go (go to step 3). If it's not, register the service manually.

3. Examples

Now, to help you understand how easy it is to use this helper class once it has been registered through Dependency Injection we have 2 basic examples:

How to retrieve the root dir

As described with our helper class ContainerParametersHelper, there's already a method created by us that returns the directory, so we just need to inject this class where we need it. In this example, we'll require this class in some controller and we will print the path of the root directory retrieved by this method as response:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;


use App\Service\ContainerParametersHelper;

class UserController extends AbstractController
{
    public function index(ContainerParametersHelper $pathHelpers){

        // Renders in the browser an empty html page with an output like:
        // /var/www/vhosts/myprojectdirectory
        return new Response($pathHelpers->getApplicationRootDir());
    } 
}

How to retrieve other container parameters

As we are using the parameter bag, you will be able to retrieve the parameters defined in the services.yaml file of your project:

# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.

# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
# /app/config/services.yaml
parameters:
    locale: 'en'

As shown in the previous services file, we have defined the locale parameter, so we can retrieve it from our service like this:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;


use App\Service\ContainerParametersHelper;

class UserController extends AbstractController
{
    public function index(ContainerParametersHelper $pathHelpers){

        // Renders in the browser an empty html page with an output like:
        // "en"
        return new Response($pathHelpers->getParameter("en"));
    } 
}

Happy coding !

This could interest you

Become a more social person