services.yaml::parameters 中的 Symfony 5.4 环境变量
Symfony 5.4 environmental variables in services.yaml::parameters
最近我决定在其中一个项目中使用 Symfony 5.4 容器来提供一些全面的 DI。它像往常一样运行良好,直到我尝试在 services.yaml::parameters
部分使用一些环境变量。
文档说明我应该绑定到环境变量
# services.yaml
parameters:
my_var: '%env(SOME_ENV_VAR)%'
它将在第一次调用时从环境变量中解析。好的。我是这样做的,这里是我得到的:
echo $container->getParameter('my_var');
// env_b057c2b619f37f36_SOME_ENV_VAR_222ed306d0932595cbdeada438ccbb2a
我确实在 $_SERVER
和 $_ENV
中看到了 SOME_ENV_VAR
。我还尝试了 Dotenv
组件以确保我没有遗漏任何东西,但徒劳无功。任何环境变量都会变成这种 env_{hash}_{VAR_NAME}_{hash}
模式。
我没有使用完整的 Symfony 安装,只是一些备用组件。我缺少什么?我应该在容器构建阶段手动填充每个环境变量吗?
容器实例化如下:
// $_ENV and $_SERVER already contain `SOME_ENV_VAR` here
require_once __DIR__ . '/vendor/autoload.php';
// `use` statements go here
$containerBuilder = new ContainerBuilder();
$loader = new YamlFileLoader(
$containerBuilder,
new FileLocator(implode(DIRECTORY_SEPARATOR, [__DIR__, 'config']))
);
$loader->load('services.yaml');
$containerBuilder->compile();
$container = $containerBuilder;
$my_var = $container->getParameter('SOME_ENV_VAR');
echo $my_var;
根据您更新的代码段,您需要使用:
$container->compile(true); // false is the default
该参数称为 resolveEnvPlaceholders。我记得前段时间它抓住了我。
仍然觉得您设置了 $_ENV 有点令人费解,但我会相信您的话。
这是我挖出的一个旧测试用例,它仍然有效:
use Symfony\Component\DependencyInjection\ContainerBuilder;
class Service
{
public function __construct(string $dsn)
{
echo $dsn . "\n";
}
}
$container = new ContainerBuilder();
$container->autowire(Service::class,Service::class)->setPublic(true)
->setArguments([
'%env(DSN)%'
]);
$container->setParameter('my_var','%env(DSN)%');
putenv('DSN=dsn_value');
$container->compile(true);
$service = $container->get(Service::class);
echo $container->getParameter('my_var') . "\n";
ContainerBuilder::compile()
的签名是:
public function compile(bool $resolveEnvPlaceholders = false)
如果你不传递它true
,它不会解析环境变量的占位符。
此外,您的示例存在问题。
您正在呼叫:
$my_var = $container->getParameter('SOME_ENV_VAR');
但是SOME_ENV_VAR
不是容器参数,而是环境变量。正确的调用是:
$my_var = $container->getParameter('my_var');
整个事情将是:
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
require_once __DIR__ . '/vendor/autoload.php';
$containerBuilder = new ContainerBuilder();
$loader = new YamlFileLoader(
$containerBuilder,
new FileLocator(implode(DIRECTORY_SEPARATOR, [__DIR__, 'config']))
);
$loader->load(__DIR__ . '/services.yaml');
$containerBuilder->compile(true);
$container = $containerBuilder;
$my_var = $container->getParameter('my_var');
echo $my_var;
最近我决定在其中一个项目中使用 Symfony 5.4 容器来提供一些全面的 DI。它像往常一样运行良好,直到我尝试在 services.yaml::parameters
部分使用一些环境变量。
文档说明我应该绑定到环境变量
# services.yaml
parameters:
my_var: '%env(SOME_ENV_VAR)%'
它将在第一次调用时从环境变量中解析。好的。我是这样做的,这里是我得到的:
echo $container->getParameter('my_var');
// env_b057c2b619f37f36_SOME_ENV_VAR_222ed306d0932595cbdeada438ccbb2a
我确实在 $_SERVER
和 $_ENV
中看到了 SOME_ENV_VAR
。我还尝试了 Dotenv
组件以确保我没有遗漏任何东西,但徒劳无功。任何环境变量都会变成这种 env_{hash}_{VAR_NAME}_{hash}
模式。
我没有使用完整的 Symfony 安装,只是一些备用组件。我缺少什么?我应该在容器构建阶段手动填充每个环境变量吗?
容器实例化如下:
// $_ENV and $_SERVER already contain `SOME_ENV_VAR` here
require_once __DIR__ . '/vendor/autoload.php';
// `use` statements go here
$containerBuilder = new ContainerBuilder();
$loader = new YamlFileLoader(
$containerBuilder,
new FileLocator(implode(DIRECTORY_SEPARATOR, [__DIR__, 'config']))
);
$loader->load('services.yaml');
$containerBuilder->compile();
$container = $containerBuilder;
$my_var = $container->getParameter('SOME_ENV_VAR');
echo $my_var;
根据您更新的代码段,您需要使用:
$container->compile(true); // false is the default
该参数称为 resolveEnvPlaceholders。我记得前段时间它抓住了我。
仍然觉得您设置了 $_ENV 有点令人费解,但我会相信您的话。
这是我挖出的一个旧测试用例,它仍然有效:
use Symfony\Component\DependencyInjection\ContainerBuilder;
class Service
{
public function __construct(string $dsn)
{
echo $dsn . "\n";
}
}
$container = new ContainerBuilder();
$container->autowire(Service::class,Service::class)->setPublic(true)
->setArguments([
'%env(DSN)%'
]);
$container->setParameter('my_var','%env(DSN)%');
putenv('DSN=dsn_value');
$container->compile(true);
$service = $container->get(Service::class);
echo $container->getParameter('my_var') . "\n";
ContainerBuilder::compile()
的签名是:
public function compile(bool $resolveEnvPlaceholders = false)
如果你不传递它true
,它不会解析环境变量的占位符。
此外,您的示例存在问题。
您正在呼叫:
$my_var = $container->getParameter('SOME_ENV_VAR');
但是SOME_ENV_VAR
不是容器参数,而是环境变量。正确的调用是:
$my_var = $container->getParameter('my_var');
整个事情将是:
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
require_once __DIR__ . '/vendor/autoload.php';
$containerBuilder = new ContainerBuilder();
$loader = new YamlFileLoader(
$containerBuilder,
new FileLocator(implode(DIRECTORY_SEPARATOR, [__DIR__, 'config']))
);
$loader->load(__DIR__ . '/services.yaml');
$containerBuilder->compile(true);
$container = $containerBuilder;
$my_var = $container->getParameter('my_var');
echo $my_var;