Symfony 从服务获取getEnvironment()

Symfony 从服务获取getEnvironment(),symfony,Symfony,在我的通知服务中,我必须通过邮件发送通知,但在dev中,我希望将所有电子邮件发送到特定的地址: if ( $this->container->get('kernel')->getEnvironment() == "dev" ) { mail( 'mymail@mail.com', $lib, $txt, $entete ); } else { mail( $to->getEmail(), $lib, $txt, $entete ); } 但是$t

在我的通知服务中,我必须通过邮件发送通知,但在dev中,我希望将所有电子邮件发送到特定的地址:

if ( $this->container->get('kernel')->getEnvironment() == "dev" ) {

    mail( 'mymail@mail.com', $lib, $txt, $entete );

} else {

    mail( $to->getEmail(), $lib, $txt, $entete );

}
但是
$this->container->get('kernel')->getEnvironment()
只在控制器中工作

我想我必须在我的服务构造函数中添加一个参数:

notification:
  class:      %project.notification.class%
  arguments: [@templating, @doctrine]

但是我没有找到任何关于此的信息。

您可以在控制器中获得$this->容器的原因是它被注入到您扩展的控制器中

例如,您可以在容器中注入并在构造函数中设置它

services.yml

notification:
  class:      %project.notification.class%
  arguments: [@templating, @doctrine]
swiftmailer:
    delivery_address: 'dev@example.com'
notification:
  class:      NotificationService
  arguments: ["%kernel.environment%"]
services:
    _defaults:
        bind:
            $kernelEnvironment: '%kernel.environment%'
NotificationService.php

<?php

private $container;

public function __construct()
{
    $this->container = $container;
}

public function mailStuff()
{
    if ( $this->container->get('kernel')->getEnvironment() == "dev" ) {
        mail( 'mymail@mail.com', $lib, $txt, $entete );  
    } else {
        mail( $to->getEmail(), $lib, $txt, $entete );
    }
}
<?php

private $env;

public function __construct($env)
{
    $this->env = $env;
}

public function mailStuff()
{
    if ( $this->env == "dev" ) {
        mail( 'mymail@mail.com', $lib, $txt, $entete );  
    } else {
        mail( $to->getEmail(), $lib, $txt, $entete );
    }
}
private $env;

public function __construct($kernelEnvironment)
{
    $this->env = $kernelEnvironment;
}

不需要注入容器。事实上,注入容器不是一个好主意,因为这样会使类依赖于DI

您应该插入环境参数:

services.yml

notification:
  class:      %project.notification.class%
  arguments: [@templating, @doctrine]
swiftmailer:
    delivery_address: 'dev@example.com'
notification:
  class:      NotificationService
  arguments: ["%kernel.environment%"]
services:
    _defaults:
        bind:
            $kernelEnvironment: '%kernel.environment%'
NotificationService.php

<?php

private $container;

public function __construct()
{
    $this->container = $container;
}

public function mailStuff()
{
    if ( $this->container->get('kernel')->getEnvironment() == "dev" ) {
        mail( 'mymail@mail.com', $lib, $txt, $entete );  
    } else {
        mail( $to->getEmail(), $lib, $txt, $entete );
    }
}
<?php

private $env;

public function __construct($env)
{
    $this->env = $env;
}

public function mailStuff()
{
    if ( $this->env == "dev" ) {
        mail( 'mymail@mail.com', $lib, $txt, $entete );  
    } else {
        mail( $to->getEmail(), $lib, $txt, $entete );
    }
}
private $env;

public function __construct($kernelEnvironment)
{
    $this->env = $kernelEnvironment;
}
在Symfony 4(也可能是3.x)中,您可以在如下控制器中获取环境:

$env = $this->getParameter('kernel.environment');

(无需通过services.yaml进行明确的控制器注入)

对于Symfony 4,您可以执行以下操作:

use Symfony\Component\HttpKernel\KernelInterface;

class SomeService
{
    /**
     * @var string
     */
    private $environment;

    /**
     * Your Service constructor.
     */
    public function __construct(KernelInterface $kernel)
    {
        $this->environment = $kernel->getEnvironment();
    }
}

$this->environment现在保存您的环境,如dev、prod或test。

多亏了dotenv,您可以使用$\u env superglobal获得.env文件中的所有环境


$\u ENV['APP\u ENV']

如果您进入一个静态类,并且没有对容器的访问权限,则始终可以在AppKernel.php->registerBundles()中执行此操作:

这样,您将始终在superglobal$\u ENV中拥有环境。

这有点像黑客,但很有魅力。

实际上,您不需要了解实际环境。例如,如果只需要在生产环境中发送空闲通知,则可以配置
send_slack_notification
参数,并在不同的环境中将其设置为true/false

然后在代码中可以执行以下操作:

if ($parameters->get('send_slack_notification') == true) {
    //send the notifications
}
通过使用此方法,您以后可以在不同的环境中打开/关闭此设置,而无需更改实现。另一个好处是,当您检查参数文件时,您可以立即看到不同环境中的所有选项,这将使调试更容易

注意


KernelInterface$kernel->getEnvironment()
可以返回小写和大写结果,具体取决于您在.env文件中的配置方式。您不应该使用它的另一个原因。

在symfony中,您可以通过$variableName绑定默认值

config/services.yaml

notification:
  class:      %project.notification.class%
  arguments: [@templating, @doctrine]
swiftmailer:
    delivery_address: 'dev@example.com'
notification:
  class:      NotificationService
  arguments: ["%kernel.environment%"]
services:
    _defaults:
        bind:
            $kernelEnvironment: '%kernel.environment%'
NotificationService.php

<?php

private $container;

public function __construct()
{
    $this->container = $container;
}

public function mailStuff()
{
    if ( $this->container->get('kernel')->getEnvironment() == "dev" ) {
        mail( 'mymail@mail.com', $lib, $txt, $entete );  
    } else {
        mail( $to->getEmail(), $lib, $txt, $entete );
    }
}
<?php

private $env;

public function __construct($env)
{
    $this->env = $env;
}

public function mailStuff()
{
    if ( $this->env == "dev" ) {
        mail( 'mymail@mail.com', $lib, $txt, $entete );  
    } else {
        mail( $to->getEmail(), $lib, $txt, $entete );
    }
}
private $env;

public function __construct($kernelEnvironment)
{
    $this->env = $kernelEnvironment;
}

没错,但正如上面的答案所述,更简单的是:Symfony内置了一个功能,可以发送特定地址的电子邮件,在这种情况下,您只需在
app/config/config_dev.yml
中设置正确的配置即可。没有必要在您的服务中处理此逻辑。Thx提供最佳实践!但我必须对slack通知(仅在prod中发送)执行相同的过程。在这种情况下,最佳实践仍然是使用配置文件。您可以有一个仅为生产YAM设置的slack address参数,该参数在dev yaml中为null,并在执行操作之前检查该参数是否为null。但是您不能在没有注入的服务中直接使用
getParameter()
?是,但是当使用Symfony直接访问超全局变量时,这不是一个好的做法。在应用程序代码中使用全局变量是一个糟糕的做法。非常非常糟糕的做法,我只编写了另一种方法