Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

symfony4 use .env config variables in a service

I am using a package that is not especially made for symfony (TNTsearch), and have put all the functions I want to use in a service I called TNTsearchHelper.php. This service requires some variables, including some that could be found in the .env file. I currently define and construct these in my class:

class TntSearchHelper
{
    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;

        $config = [
            'driver'    => 'mysql',
            'host'      => 'localhost',
            'database'  => 'databasename',
            'username'  => 'user',
            'password'  => 'pw',
            'storage'   => 'my/path/to/file',
            'charset'   => 'utf8',
            'collation' => 'utf8_general_ci',
        ];

        $this->config = $config;
    }

What I would really like is to simply use the variables for my database that are set in the .env file. Is there any way to do this? This service is not registered in services.yaml because this is not neccesary with the autowire: true option, so I don't have any config options/file for my service in the config and wonder if I can keep it that way.

like image 722
Dirk J. Faber Avatar asked Jul 23 '18 12:07

Dirk J. Faber


People also ask

Can I use variables in .env file?

You can set default values for environment variables using a .env file, which Compose automatically looks for in project directory (parent folder of your Compose file). Values set in the shell environment override those set in the .env file.

How do I import a .env variable?

On the Projects page, select the project that you want to import environment variables to, and click Properties to open the Project Properties window. On the General page, click Environment. In the Environment Variables dialog, click Import from File.

How do I store .env credentials?

To save passwords and secret keys in environment variables on Windows, you will need to open Advance System Setting. You can navigate to control panel > System and Security > System > Advanced system Settings . Now in Advance System Setting click on Environment Variables .

Is .env a config file?

In case you are still wondering what all this means, well, you are probably new to the . env file. It's actually a simple configuration text file that is used to define some variables you want to pass into your application's environment.


2 Answers

Yes. It's possible. If you want to use env variables for configuration, you have two options:

1.Use getenv:

$config = [
    'driver'    => 'mysql',
    'host'      => getenv('MYSQL_HOST'),
    'database'  => getenv('MYSQL_DB'),
    'username'  => getenv('MYSQL_LOGIN'),
    'password'  => getenv('MYSQL_PASSWORD'),
    'storage'   => 'my/path/to/file',
    'charset'   => 'utf8',
    'collation' => 'utf8_general_ci',
];

2.Configure your service in services.yaml:

services:
  App\TntSearchHelper:
    arguments:
      - '%env(MYSQL_HOST)%'
      - '%env(MYSQL_DB)%'
      - '%env(MYSQL_LOGIN)%'
      - '%env(MYSQL_PASSWORD)%'

And change your __construct function to this:

public function __construct(string $host, string $db, string $login, string $password, EntityManagerInterface $em) 
{
    $this->em = $em;
    $config = [
        'driver'    => 'mysql',
        'host'      => $host,
        'database'  => $db,
        'username'  => $login,
        'password'  => $password,
        'storage'   => 'my/path/to/file',
        'charset'   => 'utf8',
        'collation' => 'utf8_general_ci',
    ];
    $this->config = $config;
}

Also make sure that all this env variables are set because there's only DATABASE_URL variable in .env file by default

like image 134
Nikita Leshchev Avatar answered Sep 30 '22 16:09

Nikita Leshchev


I know three possibilities. Each case has 03 steps configuration :
1 - declare yours variables in env.
2 - config service file
3 - and call your parameter

_ In controllers extending from the AbstractController, and use the getParameter() helper :

YAML file config

# config/services.yaml
parameters:
    kernel.project_dir: "%env(variable_name)%"
    app.admin_email: "%env(variable_name)%"

In your service,

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class UserController extends AbstractController
{
    // ...

    public function index(): Response
    {
        $projectDir = $this->getParameter('kernel.project_dir');
        $adminEmail = $this->getParameter('app.admin_email');

        // ...
    }
}


_ In services and controllers not extending from AbstractController, inject the parameters as arguments of their constructors.

YAML file config

# config/services.yaml
parameters:
    app.contents_dir: "%env(variable_name)%"

services:
    App\Service\MessageGenerator:
        arguments:
            $contentsDir: '%app.contents_dir%'

In your service,

class MessageGenerator
{
    private $params;

    public function __construct(string $contentsDir)
    {
        $this->params = $contentsDir;
    }

    public function someMethod()
    {
        $parameterValue = $this->params;
        // ...
    }
}


_ Finally, if some service needs access to lots of parameters, instead of injecting each of them individually, you can inject all the application parameters at once by type-hinting any of its constructor arguments with the ContainerBagInterface:

YAML file config

# config/services.yaml
parameters:
    app.parameter_name: "%env(variable_name)%"

In your service,

use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;

class MessageGenerator
{
    private $params;

    public function __construct(ContainerBagInterface $params)
    {
        $this->params = $params;
    }

    public function someMethod()
    {
        $parameterValue = $this->params->get('app.parameter_name');
        // ...
    }
}


source Accessing Configuration Parameters

like image 40
belem Avatar answered Sep 30 '22 15:09

belem