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 !