Php 在运行时使用env()在Symfony 3.2中加载外部环境参数,返回未解析的值

Php 在运行时使用env()在Symfony 3.2中加载外部环境参数,返回未解析的值,php,dependency-injection,configuration,symfony,ioc-container,Php,Dependency Injection,Configuration,Symfony,Ioc Container,我在使用symfony 3.2控制台、配置和YAML组件的应用程序中有一个参数文件,我尝试在服务容器参数中设置变量 我创建了容器生成器 $container = new ContainerBuilder(); 我正在使用文件定位器查找资源: $container = new ContainerBuilder(); 加载资源的加载程序解析程序 LoaderResolver(); 使用荷载法: $this->load('parameters.yml'); parameters.yml文

我在使用symfony 3.2控制台、配置和YAML组件的应用程序中有一个参数文件,我尝试在服务容器参数中设置变量

我创建了容器生成器

$container = new ContainerBuilder();
我正在使用文件定位器查找资源:

$container = new ContainerBuilder();
加载资源的加载程序解析程序

LoaderResolver();
使用荷载法:

$this->load('parameters.yml');
parameters.yml文件:

parameters:
  database:
    driver: pdo_mysql
    host: 127.0.0.1
    dbname: dbname
    user: env(VAL1)
    password: env(VAL2)
  Local: us-en
编译容器并尝试检查从参数包获取值后:

$container->getParameterBag()->all()
其返回值如下所示:

env_VAL1_3EC776; EDC429C1734ED780A29A0AF538,env_VAL2_3ec776edc429c1734ed780a29a0af538

我认为容器无法从环境中解析这些值

注意:我使用以下方法设置环境变量:

$ export VAL1='SOME TEXT'
有人知道为什么吗?

请尝试:

parameters:
database:
    driver: pdo_mysql
    host: 127.0.0.1
    dbname: dbname
    user: '%env(VAL1)%'
    password: '%env(VAL2)%'
log_path: /logs
我想这就是问题所在。请参阅本文档以获取参考:

所以我花了一些时间调查这个“问题”,下面是我发现的

使
env(VAL1)
thingy工作的唯一方法是使用
PHPDumper
将容器生成PHP文件,然后使用生成的容器。没有其他方法可以使它工作,因为它只解析该文件中的环境

在普通的Symfony项目中,有一个生成的
var/cache/dev/appDevDebugProjectContainer.php
文件。有一个方法
getDynamicParameter
如下所示

 private function getDynamicParameter($name)
    {
        switch ($name) {
            case 'kernel.root_dir': $value = ($this->targetDirs[3].'/app'); break;
            case 'kernel.logs_dir': $value = ($this->targetDirs[2].'/logs'); break;
            case 'user': $value = $this->getEnv('VAL1'); break;
            case 'session.save_path': $value = ($this->targetDirs[3].'/app/../var/sessions/dev'); break;
            case 'router.resource': $value = ($this->targetDirs[3].'/app/config/routing_dev.yml'); break;
            default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name));
        }
        $this->loadedDynamicParameters[$name] = true;

        return $this->dynamicParameters[$name] = $value;
    }
它是唯一评估
env(VAL1)
的地方

因此,对于您的情况,解决方案如下

我使用了简化的
参数。yml

parameters:
    user: '%env(VAL1)%'
导出
我做了:

export VAL1=abc
PHP代码:

$container = new ContainerBuilder();

$loader = new YamlFileLoader(
    $container,
    new FileLocator('.')
);

$loader->load('parameters.yml');

$container->compile();

$dumper = new PhpDumper($container);

$content = $dumper->dump(
    [
        'class' => 'DumpedContainer',
        'base_class' => 'Container',
        'file' => 'DumpedContainer.php',
        'debug' => true
    ]
);

// Use this code if you want to write file to the disk
$cache = new ConfigCache('DumpedContainer.php', true);
$cache->write($content, $container->getResources());
require_once $cache->getPath();

// ... otherwise use this code
//$content = str_replace('<?php', '', $content);
//eval($content);

$container = new DumpedContainer();

$user = $container->getParameter('user'); // $user = 'abc'

这个解决方案工作得很好,但看看它,我想知道你的项目是否真的需要它?如果您使用Symfony\Bundle\FrameworkBundle\Test\WebTestCase而不是\PHPUnit\u Framework\u TestCase Symfony3,那么会为您带来奇迹

$client = static::createClient();
$this->container = $client->getContainer();
$user = $container->getParameter('user'); // $user = 'abc'
看看

使用此方法,您还可以使用*\u test.yml特定文件调整Symfony配置


我认为这是正确的方法。

您是否尝试过将
%env(VAL1)%“
替换为
env(VAL1)
是的,它不起作用,它向我显示了上面的值。我确实更改了参数,但什么也没有发生。我认为问题与容器扩展类型有关,或者编译不确定。您是否使用以下命令清除缓存:
php bin/console cache:clear--env=prod
?我使用的是Symfony控制台和配置组件,而不是Symfony项目中的组件。
getenv(VAL1)
是否有效?尝试使用单引号和不使用单引号。让我知道,我会更新我的帖子。谢谢你的回答,目前我在我的应用程序中不做任何缓存,我想在我的应用程序中不添加缓存支持的情况下使用它。您分享了一个非常有用的信息,我将尝试您的代码,并尝试向您提供我的反馈。
$client = static::createClient();
$this->container = $client->getContainer();
$user = $container->getParameter('user'); // $user = 'abc'