symfony4 在服务中使用 .env 配置变量

symfony4 use .env config variables in a service

我正在使用一个不是专门为 symfony (TNTsearch) 制作的包,并将我想使用的所有功能放在我称为 TNTsearchHelper.php 的服务中。此服务需要一些变量,包括可以在 .env 文件中找到的一些变量。我目前在 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;
    }

我真正想要的是简单地使用 .env 文件中为我的数据库设置的变量。有什么办法吗?此服务未在 services.yaml 中注册,因为这不是 autowire: true 选项所必需的,所以我在 config 中的服务没有任何配置 options/file 并且想知道如果我能保持这种状态。

是的。这是可能的。如果你想使用环境变量进行配置,你有两个选择:

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 您在 services.yaml 的服务:

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

并将您的 __construct 函数更改为:

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;
}

还要确保设置了所有这些环境变量,因为默认情况下 .env 文件中只有 DATABASE_URL 变量

我知道三种可能。每个案例都有 03 个步骤配置:
1 - 在环境中声明你的变量。
2 - 配置服务文件
3 - 并调用你的参数

_ 在从 AbstractController 扩展的控制器中,并使用 getParameter() 助手:

YAML 文件配置

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

为您服务,

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');

        // ...
    }
}


_ 在未从 AbstractController 扩展的服务和控制器中,将参数作为其构造函数的参数注入。

YAML 文件配置

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

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

为您服务,

class MessageGenerator
{
    private $params;

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

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


_ 最后,如果某些服务需要访问大量参数,而不是单独注入每个参数,您可以通过 type-hinting 它的任何构造函数一次注入所有应用程序参数ContainerBagInterface 的参数:

YAML 文件配置

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

为您服务,

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');
        // ...
    }
}


来源 Accessing Configuration Parameters