In older versions of Symfony, we used to define parameters that didn't change on the deployment machine inside the config.yml
file:
# app/config/config.yml
# ...
parameters:
locale: en
framework:
# ...
# any string surrounded by two % is replaced by that parameter value
default_locale: "%locale%"
# ...
However, in Symfony 4, a lot of the variables that could be used in here moved to the env files or those that didn't change on the deployment machines, inside the services.yaml
file. For a lot of new developers on this version of the framework, is usually unclear how to retrieve those parameters in the most common places of the project like Controllers and Services.
In this short article, we will explain you how to retrieve easily those parameters from inside the controllers and services easily.
1. Be sure autowire is enabled and you have some parameters
In order to use the default way of retrieving parameters from your services.yaml
file, you will need to be sure that the autowire and autoconfigure properties are enabled in your project, you can check if its enabled in the same services.yaml
file where you can define parameters for your services:
# app/config/services.yaml
# Some retrievable parameters
parameters:
uploads_directory: '%kernel.project_dir%/public/uploads'
download_directory: '%kernel.project_dir%/public/downloads'
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.
Knowing that these properties are enabled and you have some X parameters that need to be obtained from either services or controller, you are ready to follow the next step.
2. Obtaining parameters within a Controller
From inside a controller, you will be able to obtain parameters, injecting automatically the ParameterBagInterface, an utility implemented by objects that manage service container parameters. You can simply include the ParameterBagInterface and catch it as argument in the method of the controller where you need to obtain some parameters as exposed in the following example:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
// 1. Include the ParameterBagInterface class
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
// 2. Basically what we do is autoinject the ParameterBagInterface as argument
// inside the method where you need to obtain a parameter from the services.yaml file
// and then, using the get method you can retrieve a specific parameter.
class MyController extends AbstractController
{
public function upload(Request $request, ParameterBagInterface $params): Response
{
// $uploadsDirectory contains:
// /var/www/vhosts/app/public/uploads
$uploadsDirectory = $params->get('uploads_directory');
// ... or retrieve them all with $params->all()
}
public function download(Request $request, ParameterBagInterface $params): Response
{
// $uploadsDirectory contains:
// /var/www/vhosts/app/public/downloads
$downloadsDirectory = $params->get('downloads_directory');
// ... or retrieve them all with $params->all()
}
}
3. Obtaining parameters within a Service
If instead of a controller, you need to obtain parameters from inside a service of your own, you can as well proceed with the mentioned logic but instead of injecting the ParameterBagInterface on every method where you need it, you need to store it into a class variable and update its value inside the constructor:
<?php
namespace App\Controller;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class MyService
{
private $params;
public function __construct(ParameterBagInterface $params)
{
$this->params = $params;
}
public function someMethod()
{
// $uploadsDirectory contains:
// /var/www/vhosts/app/public/uploads
$uploadsDirectory = $params->get('uploads_directory');
// ... or retrieve them all with $params->all()
}
}
Happy coding !