symfony/yaml 支持 symfony/config 不解析环境变量
symfony/yaml backed symfony/config not parsing environment variables
我重新创建了一个简单的示例 in this tiny github repo。我正在尝试使用 symfony/dependency-injection
配置 monolog/monolog
以将日志写入 php://stderr
。我正在使用一个名为 services.yml 的 yaml 文件来配置依赖项注入。
如果我的 yml 文件如下所示,一切正常:
parameters:
log.file: 'php://stderr'
log.level: 'DEBUG'
services:
stream_handler:
class: \Monolog\Handler\StreamHandler
arguments:
- '%log.file%'
- '%log.level%'
log:
class: \Monolog\Logger
arguments: [ 'default', ['@stream_handler'] ]
不过,我的目标是分别从环境变量$APP_LOG
和LOG_LEVEL
中读取日志文件的路径和日志级别。根据 The symphony documentations on external paramaters 在 services.yml 文件中正确的做法是这样的:
parameters:
log.file: '%env(APP_LOG)%'
log.level: '%env(LOGGING_LEVEL)%'
在我的示例应用程序中,我验证了 PHP 可以使用以下内容读取这些环境变量:
echo "Hello World!\n\n";
echo 'APP_LOG=' . (getenv('APP_LOG') ?? '__NULL__') . "\n";
echo 'LOG_LEVEL=' . (getenv('LOG_LEVEL') ?? '__NULL__') . "\n";
当我使用带有硬编码值的原始 services.yml 时,它将以下内容写入浏览器。:
Hello World!
APP_LOG=php://stderr
LOG_LEVEL=debug
但是,如果我在 services.yml 中使用 %env(VAR_NAME)% 语法,我会收到以下错误:
Fatal error: Uncaught UnexpectedValueException: The stream or file "env_PATH_a61e1e48db268605210ee2286597d6fb" could not be opened: failed to open stream: Permission denied in /var/www/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php:107 Stack trace: #0 /var/www/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php(37): Monolog\Handler\StreamHandler->write(Array) #1 /var/www/vendor/monolog/monolog/src/Monolog/Logger.php(337): Monolog\Handler\AbstractProcessingHandler->handle(Array) #2 /var/www/vendor/monolog/monolog/src/Monolog/Logger.php(532): Monolog\Logger->addRecord(100, 'Initialized dep...', Array) #3 /var/www/html/index.php(17): Monolog\Logger->debug('Initialized dep...') #4 {main} thrown in /var/www/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php on line 107
我做错了什么?
好的,你需要一些东西。首先,您需要 Symfony 3.3 版,它仍处于测试阶段。 3.2是我遇到这个的时候发布的版本。其次,您需要 "compile" 环境变量。
使用以下值和 运行 composer update
编辑您的 composer.json
。您可能需要更新其他依赖项。您可以将 ^3.3
替换为 dev-master
.
"symfony/config": "^3.3",
"symfony/console": "^3.3",
"symfony/dependency-injection": "^3.3",
"symfony/yaml": "^3.3",
如果您有其他 symfony 组件,您可能必须为 symfony/__WHATEVER__
执行此操作。
现在,在将 yaml 配置加载到编译它的依赖项容器后,您就可以编写代码了。
所以在你在这里排队之后(可能在 bin/console):
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(__DIR__ . DIRECTORY_SEPARATOR . '..'));
$loader->load('services.yml');
这样做:
$container->compile(true);
您的 IDE 的智能感知可能会告诉您编译不带参数。没关系。那是因为 compile() grabs its args indirectly via func_get_arg().
public function compile(/*$resolveEnvPlaceholders = false*/)
{
if (1 <= func_num_args()) {
$resolveEnvPlaceholders = func_get_arg(0);
} else {
. . .
}
参考资料
加载 services.yaml
文件后使用此命令应该会有帮助。
$containerBuilder->compile(true);
假设您的文件也通过此方法也执行的正确配置检查得到验证。参数是 $resolveEnvPlaceholders
,它使 yaml 服务配置可以访问环境变量。
我重新创建了一个简单的示例 in this tiny github repo。我正在尝试使用 symfony/dependency-injection
配置 monolog/monolog
以将日志写入 php://stderr
。我正在使用一个名为 services.yml 的 yaml 文件来配置依赖项注入。
如果我的 yml 文件如下所示,一切正常:
parameters:
log.file: 'php://stderr'
log.level: 'DEBUG'
services:
stream_handler:
class: \Monolog\Handler\StreamHandler
arguments:
- '%log.file%'
- '%log.level%'
log:
class: \Monolog\Logger
arguments: [ 'default', ['@stream_handler'] ]
不过,我的目标是分别从环境变量$APP_LOG
和LOG_LEVEL
中读取日志文件的路径和日志级别。根据 The symphony documentations on external paramaters 在 services.yml 文件中正确的做法是这样的:
parameters:
log.file: '%env(APP_LOG)%'
log.level: '%env(LOGGING_LEVEL)%'
在我的示例应用程序中,我验证了 PHP 可以使用以下内容读取这些环境变量:
echo "Hello World!\n\n";
echo 'APP_LOG=' . (getenv('APP_LOG') ?? '__NULL__') . "\n";
echo 'LOG_LEVEL=' . (getenv('LOG_LEVEL') ?? '__NULL__') . "\n";
当我使用带有硬编码值的原始 services.yml 时,它将以下内容写入浏览器。:
Hello World!
APP_LOG=php://stderr
LOG_LEVEL=debug
但是,如果我在 services.yml 中使用 %env(VAR_NAME)% 语法,我会收到以下错误:
Fatal error: Uncaught UnexpectedValueException: The stream or file "env_PATH_a61e1e48db268605210ee2286597d6fb" could not be opened: failed to open stream: Permission denied in /var/www/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php:107 Stack trace: #0 /var/www/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php(37): Monolog\Handler\StreamHandler->write(Array) #1 /var/www/vendor/monolog/monolog/src/Monolog/Logger.php(337): Monolog\Handler\AbstractProcessingHandler->handle(Array) #2 /var/www/vendor/monolog/monolog/src/Monolog/Logger.php(532): Monolog\Logger->addRecord(100, 'Initialized dep...', Array) #3 /var/www/html/index.php(17): Monolog\Logger->debug('Initialized dep...') #4 {main} thrown in /var/www/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php on line 107
我做错了什么?
好的,你需要一些东西。首先,您需要 Symfony 3.3 版,它仍处于测试阶段。 3.2是我遇到这个的时候发布的版本。其次,您需要 "compile" 环境变量。
使用以下值和 运行 composer update
编辑您的 composer.json
。您可能需要更新其他依赖项。您可以将 ^3.3
替换为 dev-master
.
"symfony/config": "^3.3",
"symfony/console": "^3.3",
"symfony/dependency-injection": "^3.3",
"symfony/yaml": "^3.3",
如果您有其他 symfony 组件,您可能必须为 symfony/__WHATEVER__
执行此操作。
现在,在将 yaml 配置加载到编译它的依赖项容器后,您就可以编写代码了。
所以在你在这里排队之后(可能在 bin/console):
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(__DIR__ . DIRECTORY_SEPARATOR . '..'));
$loader->load('services.yml');
这样做:
$container->compile(true);
您的 IDE 的智能感知可能会告诉您编译不带参数。没关系。那是因为 compile() grabs its args indirectly via func_get_arg().
public function compile(/*$resolveEnvPlaceholders = false*/)
{
if (1 <= func_num_args()) {
$resolveEnvPlaceholders = func_get_arg(0);
} else {
. . .
}
参考资料
加载 services.yaml
文件后使用此命令应该会有帮助。
$containerBuilder->compile(true);
假设您的文件也通过此方法也执行的正确配置检查得到验证。参数是 $resolveEnvPlaceholders
,它使 yaml 服务配置可以访问环境变量。