This problem is not very common and happens when you use SwiftMailer with a Gmail account to send emails (even if you use a framework like Laravel, Symfony CakePHP). Some developers have faced the same problem, the code works as expected locally, in your development machine but not on the deployment server.
A lot of developers have faced this issue while sending emails using Swift Mailer with Gmail, pitifully every possible solution may not work for everyone. In this article we are going to share a couple of possible solutions that may help to solve this problem in your project.
1. gethostbyname maybe your enemy or ally
The gethostbyname
function of PHP get the IPv4 address corresponding to a given Internet host name. In some cases, this function has helped to make the code works, but for others providing the smtp address as a string does the trick (we recommend you to test both and see what happens):
<?php
// For some users works using the gethostbyname function
$smtp_host_ip = gethostbyname('smtp.gmail.com');
// But for others only the smtp address
$smtp_host_ip = 'smtp.gmail.com';
$transport = \Swift_SmtpTransport::newInstance($smtp_host_ip, 465, 'ssl')->setUsername('[email protected]')->setPassword('qweqwe+');
$mailer = \Swift_Mailer::newInstance($transport);
$message = \Swift_Message::newInstance()
->setFrom(array("[email protected]" => 'John Doe'))
->setTo(array("[email protected]" => 'John Doe'));
$message->setBody('<h3>Contact message</h3>', 'text/html');
$mailer->send($message);
2. Change the smtp of Gmail
You can connect to Gmail mail servers using SMTP, SSL/TLS. To do that with Swift Mailer you need to connect to smtp.gmail.com
on port 465, however if you receive the mentioned exception while you try to send the email, change the smtp address of gmail, instead of smtp.gmail.com
use any of the following IPs or addresses:
- 173.194.65.108
- 173.194.205.108
- 74.125.133.108
- gmail-smtp-msa.l.google.com
A recommendation is to do ping to the smtp.gmail.com
address with the terminal in your server, that should print the IP address of the SMTP that you can use to send the email:
As mentioned previously, this could work in some cases.
3. If you use Symfony
If you're working in a symfony project, your code to send a email with SwiftMailer will probably look like:
public function indexAction($name)
{
$message = \Swift_Message::newInstance()
->setSubject('Hello Email')
->setFrom('[email protected]')
->setTo('[email protected]')
->setBody(
$this->renderView(
// app/Resources/views/Emails/registration.html.twig
'Emails/registration.html.twig',
array('name' => $name)
),
'text/html'
)
/*
* If you also want to include a plaintext version of the message
->addPart(
$this->renderView(
'Emails/registration.txt.twig',
array('name' => $name)
),
'text/plain'
)
*/
;
$this->get('mailer')->send($message);
return $this->render(...);
}
Your code doesn't handle credentials directly as they're retrieven through the parameters.yml
file or the config.yml
, whatever the case it is, a trick that may help you to work around. Start by modifying the transport option in your parameters.yml
(or config.yml
according to your workflow):
# Swiftmailer Configuration
swiftmailer:
transport: mail
Then set the spool type to memory:
# app/config/config.yml
swiftmailer:
# ...
spool: { type: memory }
Or in the parameters.yml
(according to your workflow):
# app/config/parameters.yml
parameters:
spool: { type: memory }
When you are using the SwiftmailerBundle to send an email from a Symfony application, it will default to sending the email immediately. You may, however, want to avoid the performance hit of the communication between Swift Mailer and the email transport, which could cause the user to wait for the next page to load while the email is sending. This can be avoided by choosing to "spool" the emails instead of sending them directly. This means that Swift Mailer does not attempt to send the email but instead saves the message to somewhere such as a file. Another process can then read from the spool and take care of sending the emails in the spool. Currently only spooling to file or memory is supported by Swift Mailer.
May the force be with you and happy coding !