如何将配置参数获取到命令中
how to get configuration parameter into a command
我正在尝试将配置参数放入命令中。
我在parameters
键下的app/config/config.yml
中添加了参数。
我可以在使用 $this->getParameter("PRAMETER_NAME")
的控制器中使用它来手动执行一些操作。
我正在编写一个命令,通过 CRON 作业自动执行相同的操作。
我找不到如何获取命令中的参数。
您可以将容器注入到声明它的命令中 ContainerAware
(更差),您可以将 ParamterBag
作为服务注入(更好)或者您可以在命令构造函数中注入参数 (最好)。
在您的命令中,您必须接受构造函数中的参数。例如:
YourCommand.php:
<?php
class YourCommand extends Command {
public function __construct(string $parameter) {
parent::__construct('app:my-command');
$this->parameter = $parameter;
}
}
services.yaml
services:
YourCommand:
arguments:
- '%parameter_name%'
参数绑定
在 Symfony 3.4 或更高版本中,recommended approach is to use Autowiring and Argument Binding。允许将变量名称的声明“绑定”为配置文件中定义的所有服务的参数,而无需明确指定使用该参数的每个服务。
在定义命令服务和自动装配的同一个配置文件中,将 bind
选项添加到 _defaults
规范,以及参数所需的变量名称。
app/config/services.yml
parameters:
PARAMETER_NAME: 'test'
services:
_defaults:
bind:
$PARAMETER_NAME: '%PARAMETER_NAME%'
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
AppBundle\:
resource: '../../src/AppBundle/*'
exclude: '../../src/AppBundle/{DependencyInjection,Entity,Tests}'
# Additional Services Below Here
之后,Symfony 将在指定为服务构造函数的参数时自动将参数值传递给绑定变量名。
src/AppBundle/Command/MyCommand.php
namespace AppBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class MyCommand extends Command
{
private $PARAMETER_NAME;
public function __construct($PARAMETER_NAME)
{
$this->PARAMETER_NAME = $PARAMETER_NAME;
parent::__construct();
}
// ...
public function execute(InputInterface $input, OutputInterface $output)
{
dump($this->PARAMETER_NAME);
exit;
}
public static function getDefaultName()
{
return 'app:my_command';
}
}
参数注入
另一种避免需要覆盖 __construct
的方法是使用方法注入参数值,方法是使用 calls
.
扩展服务定义
app/config/services.yml
parameters:
PARAMETER_NAME: 'test'
services:
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
AppBundle\:
resource: '../../src/AppBundle/*'
exclude: '../../src/AppBundle/{DependencyInjection,Entity,Tests}'
AppBundle\Command\MyCommand:
calls:
- [setParameterName, ['%PARAMETER_NAME%']]
# Additional Services Below Here
src/AppBundle/Command/MyCommand.php
namespace AppBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class MyCommand extends Command
{
private $parameterName;
// ...
public function execute(InputInterface $input, OutputInterface $output)
{
dump($this->parameterName);
exit;
}
public function setParameterName($value)
{
$this->parameterName = $value;
}
}
或者,依赖注入可用于将 Container 或 ParameterBag 注入到命令中,使它的功能类似于 Controller。
Injecting the entire Container or ParameterBag is highly
discouraged.
Only inject the parameter(s) and service(s) that are needed
instead.
在以下任一示例中,确保启用 autowire
和 autoconfigure
。
app/config/services.yml
parameters:
PARAMETER_NAME: 'test'
services:
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
AppBundle\:
resource: '../../src/AppBundle/*'
exclude: '../../src/AppBundle/{DependencyInjection,Entity,Tests}'
# Additional Services Below Here
ContainerAwareCommand
(从 Symfony 4.2 开始贬值 - 在 Syfmony 5.0+ 中移除)
使用 ContainerAwareCommand
与参数注入类似,但不是调用 setParameterName()
。启用 autowiring
和 autoconfig
后,Symfony 将使用从 ContainerAwareInterface
.
实现的 setContainer()
自动注入整个容器
src/AppBundle/Command/MyCommand.php
namespace AppBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class MyCommand extends ContainerAwareCommand
{
// ...
public function execute(InputInterface $input, OutputInterface $output)
{
dump($this->getContainer()->getParameter('PARAMETER_NAME'));
exit;
}
}
参数包注入
需要 Symfony 4.1+
要在启用 autowire
时使用依赖注入注入 ParameterBag,请将 ParameterBagInterface
添加到服务构造函数。
src/AppBundle/Command/MyCommand.php
namespace AppBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class MyCommand extends Command
{
private $parameterBag;
public function __construct(ParameterBagInterface $parameterBag)
{
$this->parameterBag = $parameterBag;
parent::__construct();
}
// ...
public function execute(InputInterface $input, OutputInterface $output)
{
dump($this->parameterBag->get('PARAMETER_NAME'));
exit;
}
public static function getDefaultName()
{
return 'app:my_command';
}
}
我正在尝试将配置参数放入命令中。
我在parameters
键下的app/config/config.yml
中添加了参数。
我可以在使用 $this->getParameter("PRAMETER_NAME")
的控制器中使用它来手动执行一些操作。
我正在编写一个命令,通过 CRON 作业自动执行相同的操作。
我找不到如何获取命令中的参数。
您可以将容器注入到声明它的命令中 ContainerAware
(更差),您可以将 ParamterBag
作为服务注入(更好)或者您可以在命令构造函数中注入参数 (最好)。
在您的命令中,您必须接受构造函数中的参数。例如:
YourCommand.php:
<?php
class YourCommand extends Command {
public function __construct(string $parameter) {
parent::__construct('app:my-command');
$this->parameter = $parameter;
}
}
services.yaml
services:
YourCommand:
arguments:
- '%parameter_name%'
参数绑定
在 Symfony 3.4 或更高版本中,recommended approach is to use Autowiring and Argument Binding。允许将变量名称的声明“绑定”为配置文件中定义的所有服务的参数,而无需明确指定使用该参数的每个服务。
在定义命令服务和自动装配的同一个配置文件中,将 bind
选项添加到 _defaults
规范,以及参数所需的变量名称。
app/config/services.yml
parameters:
PARAMETER_NAME: 'test'
services:
_defaults:
bind:
$PARAMETER_NAME: '%PARAMETER_NAME%'
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
AppBundle\:
resource: '../../src/AppBundle/*'
exclude: '../../src/AppBundle/{DependencyInjection,Entity,Tests}'
# Additional Services Below Here
之后,Symfony 将在指定为服务构造函数的参数时自动将参数值传递给绑定变量名。
src/AppBundle/Command/MyCommand.php
namespace AppBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class MyCommand extends Command
{
private $PARAMETER_NAME;
public function __construct($PARAMETER_NAME)
{
$this->PARAMETER_NAME = $PARAMETER_NAME;
parent::__construct();
}
// ...
public function execute(InputInterface $input, OutputInterface $output)
{
dump($this->PARAMETER_NAME);
exit;
}
public static function getDefaultName()
{
return 'app:my_command';
}
}
参数注入
另一种避免需要覆盖 __construct
的方法是使用方法注入参数值,方法是使用 calls
.
app/config/services.yml
parameters:
PARAMETER_NAME: 'test'
services:
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
AppBundle\:
resource: '../../src/AppBundle/*'
exclude: '../../src/AppBundle/{DependencyInjection,Entity,Tests}'
AppBundle\Command\MyCommand:
calls:
- [setParameterName, ['%PARAMETER_NAME%']]
# Additional Services Below Here
src/AppBundle/Command/MyCommand.php
namespace AppBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class MyCommand extends Command
{
private $parameterName;
// ...
public function execute(InputInterface $input, OutputInterface $output)
{
dump($this->parameterName);
exit;
}
public function setParameterName($value)
{
$this->parameterName = $value;
}
}
或者,依赖注入可用于将 Container 或 ParameterBag 注入到命令中,使它的功能类似于 Controller。
Injecting the entire Container or ParameterBag is highly discouraged. Only inject the parameter(s) and service(s) that are needed instead.
在以下任一示例中,确保启用 autowire
和 autoconfigure
。
app/config/services.yml
parameters:
PARAMETER_NAME: 'test'
services:
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
AppBundle\:
resource: '../../src/AppBundle/*'
exclude: '../../src/AppBundle/{DependencyInjection,Entity,Tests}'
# Additional Services Below Here
ContainerAwareCommand
(从 Symfony 4.2 开始贬值 - 在 Syfmony 5.0+ 中移除)
使用 ContainerAwareCommand
与参数注入类似,但不是调用 setParameterName()
。启用 autowiring
和 autoconfig
后,Symfony 将使用从 ContainerAwareInterface
.
setContainer()
自动注入整个容器
src/AppBundle/Command/MyCommand.php
namespace AppBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class MyCommand extends ContainerAwareCommand
{
// ...
public function execute(InputInterface $input, OutputInterface $output)
{
dump($this->getContainer()->getParameter('PARAMETER_NAME'));
exit;
}
}
参数包注入
需要 Symfony 4.1+
要在启用 autowire
时使用依赖注入注入 ParameterBag,请将 ParameterBagInterface
添加到服务构造函数。
src/AppBundle/Command/MyCommand.php
namespace AppBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class MyCommand extends Command
{
private $parameterBag;
public function __construct(ParameterBagInterface $parameterBag)
{
$this->parameterBag = $parameterBag;
parent::__construct();
}
// ...
public function execute(InputInterface $input, OutputInterface $output)
{
dump($this->parameterBag->get('PARAMETER_NAME'));
exit;
}
public static function getDefaultName()
{
return 'app:my_command';
}
}