如何在Symfony 4中使用实例正确调用函数

如何在Symfony 4中使用实例正确调用函数

问题描述:

I'm trying to send an email with SMTP in Symfony 4 and I have the following function as per the docs.

public function send_smtp(\Swift_Mailer $mailer)
{
    $message = (new \Swift_Message('Hello Email'))
        ->setFrom('send@example.com')
        ->setTo('MyEmail@gmail.com')
        ->setBody('test email content');
    $mailer->send($message);
}

However, I want to call this function from a different one like

$this->send_smtp();

But it complains about 'No parameters are passed' and

$this->send_smtp(\Swift_Mailer);

also gives the error message

Undefined constant 'Swift_Mailer'

What can be the problem and how could it be solved?

There are a few solutions possible. You can add the parameter with typehinting in your action and then use it to call your function:

/**
 * @Route("/something")
 */
public function something(\Swift_Mailer $mailer)
{
    $this->send_smtp($mailer);
}

or you can retrieve the service from the container in the send_smtp function:

public function send_smtp()
{
    $mailer = $this->get('mailer');

    $message = (new \Swift_Message('Hello Email'))
        ->setFrom('send@example.com')
        ->setTo('MyEmail@gmail.com')
        ->setBody('test email content');

    $mailer->send($message);

}

Create service e.g.

namespace App\Service\Mailer;

class Mailer
{
    private $mailer;

    public function __construct(\Swift_Mailer $mailer)
    {
        $this->mailer = $mailer;
    }

    public function send_smtp()
    {
        $message = (new \Swift_Message('Hello Email'))
            ->setFrom('send@example.com')
            ->setTo('MyEmail@gmail.com')
            ->setBody('test email content');

        $this->mailer->send($message);
    }
}

And now you can inject this service wherever you want (e.g. to your Controller action or in another service) via __construct:

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

public function someAction()
{
    $this->mailer->send_smtp()
}

Or you can inject it via method or via property. You can read more about injections here: https://symfony.com/doc/current/components/dependency_injection.html

P.S. I don't recommend you use container's method get because this method works only for public services, but in Symfony 4 services are private by default.