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

SMS*_*MSM 4 php configuration dependency-injection ioc-container symfony

我在使用symfony 3.2 console,config和YAML组件的应用程序中有一个参数文件,我尝试在Service Container参数中设置环境变量的外部参数.

我创建容器构建器.

$container = new ContainerBuilder();
Run Code Online (Sandbox Code Playgroud)

我使用文件定位器来定位资源:

$container = new ContainerBuilder();
Run Code Online (Sandbox Code Playgroud)

加载器解析器加载资源

LoaderResolver();
Run Code Online (Sandbox Code Playgroud)

并使用加载方法:

$this->load('parameters.yml');
Run Code Online (Sandbox Code Playgroud)

parameters.yml文件:

parameters:
  database:
    driver: pdo_mysql
    host: 127.0.0.1
    dbname: dbname
    user: env(VAL1)
    password: env(VAL2)
  Local: us-en
Run Code Online (Sandbox Code Playgroud)

编译容器后,尝试从参数包中检查获取值:

$container->getParameterBag()->all()
Run Code Online (Sandbox Code Playgroud)

它返回我的价值如下:

env_VAL1_3ec776edc429c1734ed780a29a0af538,env_VAL2_3ec776edc429c1734ed780a29a0af538

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

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

$ export VAL1='SOME TEXT'
Run Code Online (Sandbox Code Playgroud)

任何人都知道为什么?

Ste*_*hka 6

所以我花了一些时间研究这个'问题',这就是我发现的......

让事情变得简单的唯一方法env(VAL1)是使用生成容器到PHP文件PHPDumper,然后使用生成的容器.没有其他方法可以使它工作,因为它只解析该文件中的环境.

在正常的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;
    }
Run Code Online (Sandbox Code Playgroud)

env(VAL1)是评估的唯一地方.

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

我使用简化parameters.yml:

parameters:
    user: '%env(VAL1)%'
Run Code Online (Sandbox Code Playgroud)

export我所做的:

export VAL1=abc
Run Code Online (Sandbox Code Playgroud)

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'
Run Code Online (Sandbox Code Playgroud)

在生成的代码中,您将看到以下执行魔术的方法

private function getDynamicParameter($name)
{
    switch ($name) {
        case 'user': $value = $this->getEnv('VAL1'); break;
        default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name));
    }
    $this->loadedDynamicParameters[$name] = true;

    return $this->dynamicParameters[$name] = $value;
}
Run Code Online (Sandbox Code Playgroud)

这个解决方案工作正常,但看着它我想知道你的项目是否真的需要这个?怎么了getenv()