Enviar Emails em PHP usando SMTP ou API: PHPMailer, Symfony Mailer e a função mail()

On maio 22, 2024
27min read
Ivan Djuric, an author at Mailtrap
Ivan Djuric Technical Content Writer @Mailtrap
Viktoriia Ivanenko Technical Content Writer @ Mailtrap

Se você está se perguntando como enviar emails em PHP, provavelmente não é o único, visto  que, segundo relatórios do W3Techs, mesmo em 2024, 76,4% de todos os sites usam PHP.

Felizmente, você veio ao lugar certo.

Tenho pesquisado o assunto há um tempo e, neste artigo, vou mostrar as opções mais populares para enviar emails em PHP.

Os processos e blocos de código que mostrarei neste artigo são compatíveis com a versão 7 do PHP e superiores.

Como enviar emails usando PHPMailer

O PHPMailer é uma das bibliotecas de envio de emails mais populares para PHP. É compatível com a maioria dos frameworks PHP (por exemplo, Laravel, Symfony, etc.) e oferece funcionalidades poderosas e vários recursos, como:

  • Autenticação SMTP
  • Criptografia Secure/MIME
  • Suporte aos protocolos TLS e SSL
  • Conteúdo em texto simples e HTML
  • Modelos multipart/HTML complexo
  • Vários formatos, anexos de string e binários
  • Suporte para imagens incorporadas
  • Proteção contra ataques de injeção de cabeçalho
  • Funcionalidade para validação de emails automática

Lembre-se de que o PHPMailer não possui envio de emails integrado. Ele pode enviar emails usando a função mail() do PHP, mas eu não recomendo devido a possíveis problemas relacionados a spam e à complexidade do processo. No entanto, se quiser ler mais sobre isso, confira nosso artigo dedicado ao PHPMailer.

Idealmente, o PHPMailer é usado com um servidor SMTP externo, o que o torna confiável e seguro, sendo uma escolha perfeita para a funcionalidade de envio de emails em sua aplicação PHP.

Então, agora, vou descrever como configurar o PHPMailer para qualquer provedor SMTP (por exemplo, Mailtrap, SendGrid, Postmark, etc.) e, mais tarde, mostrarei como usá-lo com o SMTP do Mailtrap para que você veja como funciona na prática.

Primeiro, instale a biblioteca via Composer, um gerenciador de dependências para PHP, recomendado pelos criadores do PHPMailer no GitHub. Você também pode seguir o manual para instalação.

Depois de instalar o Composer, adicione esta linha ao seu arquivo composer.json:

"phpmailer/phpmailer": "^6.9"

ou execute o seguinte comando:

composer require phpmailer/phpmailer

Alternativamente, você pode adicionar o PHPMailer manualmente se não quiser instalar o Composer, o que pode ser útil em um ambiente de teste. Para fazer isso, baixe os arquivos com o código-fonte do PHPMailer, copie o conteúdo da pasta PHPMailer para um dos diretórios include_path especificados na sua configuração PHP e carregue cada arquivo de classe manualmente:

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'path/to/PHPMailer/src/Exception.php';
require 'path/to/PHPMailer/src/PHPMailer.php';
require 'path/to/PHPMailer/src/SMTP.php';

Agora, tudo o que resta é adicionar as credenciais fornecidas pelo seu provedor de serviços SMTP (por exemplo, nome de usuário, senha, porta SMTP, etc.). Elas devem se parecer com isto:

$mail->isSMTP();
$mail->Host = 'live.smtp.mailtrap.io';
$mail->SMTPAuth = true;
$mail->Username = 'api';
$mail->Password = '1a2b3c4d5e6f7g';
$mail->SMTPSecure = 'tls';
$mail->Port = 587;

E aqui está como fica junto com o código que você pode usar para enviar emails:

<?php
// Start with PHPMailer class
use PHPMailer\PHPMailer\PHPMailer;
require_once './vendor/autoload.php';
// criar um novo objeto
$mail = new PHPMailer();
// configurar um SMTP
$mail->isSMTP();
$mail->Host = 'live.smtp.mailtrap.io';
$mail->SMTPAuth = true;
$mail->Username = 'api';
$mail->Password = '1a2b3c4d5e6f7g';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;

$mail->setFrom('confirmation@registered-domain', 'Your Hotel');
$mail->addAddress('receiver@gmail.com', 'Me');
$mail->Subject = 'Thanks for choosing Our Hotel!';
// Definir HTML 
$mail->isHTML(TRUE);
$mail->Body = '<html>Hi there, we are happy to <br>confirm your booking.</br> Please check the document in the attachment.</html>';
$mail->AltBody = 'Hi there, we are happy to confirm your booking. Please check the document in the attachment.';
// adicionar anexo 
// adicionar apenas '/path/to/file.pdf'
$attachmentPath = './confirmations/yourbooking.pdf';
if (file_exists($attachmentPath)) {
    $mail->addAttachment($attachmentPath, 'yourbooking.pdf');
}

// enviar a mensagem
if(!$mail->send()){
    echo 'Message could not be sent.';
    echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
    echo 'Message has been sent';
}

Como enviar emails usando Symfony Mailer

Em 2024, o Pear:: Mail e o Swift Mailer estão bastante desatualizados, então nossa próxima escolha óbvia para enviar emails em PHP é o Symfony. É um framework super flexível e, graças aos novos componentes Mailer e Mime introduzidos na versão 4.3 do Symfony, oferece os seguintes recursos:

  • Inline do CSS
  • Integração com template Twig
  • Anexos de ficheiros
  • Assinatura e criptografia de mensagens
  • Integração direta com os provedores de email mais populares
  • Envio de emails assíncrono com Symfony Messenger

Assim como o PHPMailer, o Symfony permite enviar emails com e sem um serviço SMTP externo, usando Sendmail ou outros transportes locais. Embora eu não seja um grande fã do programa Sendmail, pois enfrenta um maior escrutínio de filtros de spam e requer muito mais manutenção, aqui está como você pode fazer isso:

Primeiro, instale os componentes Mime e Mailer, assim:

composer require symfony/mailer

Em seguida, execute o seguinte script:

<?php

use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mailer\Transport\SendmailTransport;
use Symfony\Component\Mime\Email;

require_once './vendor/autoload.php';

// Criar o transporte Sendmail
$transport = new SendmailTransport();

// Criar o Mailer usando o Transporte criado
$mailer = new Mailer($transport);

// Criar um novo email
$email = (new Email())
    ->from('hello@example.com')
    ->to('you@example.com')
    ->subject('Using Sendmail with Symfony!')
    ->text('Sending emails with Sendmail is easy!')
    ->html('<p>See Twig integration for better HTML integration!</p>');

// Enviar o email
$mailer->send($email);

Por outro lado, se você quiser enviar seus emails de forma segura e com uma maior taxa de entregabilidade, aqui está um snippet que você pode usar com Symfony e um SMTP externo:

<?php

use Symfony\Component\Mailer\Mailer; 
use Symfony\Component\Mailer\Transport\Smtp\SmtpTransport; 
use Symfony\Component\Mime\Email;

require_once './vendor/autoload.php';


$transport = (new Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport
('smtp.server.com', 587))
                ->setUsername('username')
                ->setPassword('password');

$mailer = new Mailer($transport); 

$email = (new Email())
            ->from('hello@registered.com')
            ->to('you@example.com')
            ->subject('É hora do Symfony Mailer!')
            ->text('Enviar emails é divertido de novo!')
            ->html('<p>Veja integração Twig para uma melhor integração HTML!</p>');

$mailer->send($email);

Para mais informações sobre o envio de emails usando Symfony Mailer, não deixe de conferir nosso guia detalhado explicando todo o processo e a documentação oficial da versão atual.

Função mail() do PHP

A função mail() do PHP é uma função integrada para enviar emails a partir do PHP, mas possui algumas limitações e desvantagens que a tornam menos popular e até uma espécie de “elefante na sala” . 🐘

Nomeadamente, é propensa a problemas de entregabilidade, pois depende da configuração do servidor de email local (ou seja, envia emails do seu servidor web), o que pode resultar em emails sendo marcados como spam ou rejeitados por provedores de email. Não possui muitos recursos avançados, como rastreamento de emails e, mais importante, pode ser vulnerável a ataques de injeção de email.

Portanto, você pode entender por que não recomendo a função mail(). No entanto, vou mostrar como ela funciona para fins explicativos.

A sintaxe da função mail() do PHP é bastante simples:

<?php
mail($to,$subject,$message,[$headers],[$parameters]);
?>

Ela usa os seguintes parâmetros obrigatórios:

  • $to = email do destinatário da sua mensagem. O formato do endereço de email pode ser user@example.com ou User <user@example.com>. Em geral, precisa estar em conformidade com RFC 2822. Isso é obrigatório.
  • $subject = o assunto do seu email.
  • $message = o corpo da sua mensagem. As linhas devem ser separadas com um Carriage Return Line Feed, CRLF, (\r\n). Cada linha não deve exceder 70 caracteres.
  • $headers = o obrigatório é o cabeçalho from:. Ele deve ser especificado, caso contrário, você receberá uma mensagem de erro como Warning: mail(): “sendmail_from” não definido no php.ini ou cabeçalho personalizado From: ausente.

Os cabeçalhos adicionais indicam outros destinatários ou cópias da sua mensagem, como CC ou BCC. Eles podem ser um array onde a chave é o nome do cabeçalho e o valor é o valor do cabeçalho. Ou podem ser uma string. Neste caso, os cabeçalhos devem ser separados com um CRLF (\r\n).

  • $parameters = para especificar os parâmetros adicionais definidos na configuração sendmail_path.

Aqui está como você pode enviar um email de texto simples com cabeçalhos adicionais:

<?php
$to = "somebody@example.com";
$subject = "O meu assunto";
$txt = "Oi mundo!";
$headers = "From: webmaster@example.com" . "\r\n" .
"CC: somebodyelse@example.com";

mail($to,$subject,$txt,$headers);
?>

Você também precisa ir até a pasta de instalação do PHP e configurar as configurações SMTP no arquivo php.ini. Mas isso só funcionará para localhost ou soluções como XAMPP, porque, como já mencionamos, a função mail() do PHP não suporta autenticação SMTP e não permite o envio de mensagens por meio de servidores externos.

Agora, se você não acreditar em mim quando digo que enviar emails HTML com a função mail() é complicado, aqui está como a parte da mensagem HTML geralmente fica:

// Mensagem
$message = '
<html>
<head>
  <title>Alerta de Revisão de Pedido</title>
</head>
<body>
  <p>Aqui estão os projetos que requerem a sua revisão em Dezembro:</p>
  <table>
    <tr>
      <th>Nome do projeto</th><th>Categoria</th><th>Estado</th><th>Data limite</th>
    </tr>
    <tr>
      <td>Projeto 1</td><td>Desenvolvimento</td><td>em espera</td><td>Dez-20</td>
    </tr>
    <tr>
      <td>Projeto 1</td><td>DevOps</td><td>em espera</td><td>Dez-21</td>
    </tr>
  </table>
</body>
</html>
';

Para enviar emails HTML, você também precisa definir o cabeçalho Content-type:

$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";

ou 

$headers['MIME-Version'] = 'MIME-Version: 1.0';
$headers['Content-type'] = text/html; charset=iso-8859-1';

E se você quiser enviar sua mensagem para vários destinatários, especifique os endereços de email deles no parâmetro $to =, separando-os com vírgula(s).

Não se esqueça de que, ao enviar emails com a função mail(), você pode enfrentar alguns graves problemas de entregabilidade de email. ❌

As mensagens enviadas não beneficiarão da configuração de SPF e DKIM no seu domínio. Portanto, as mensagens provavelmente serão tratadas como spam pelo MTA (Mail Transfer Agent) receptor, e, por consequência a entregabilidade geral das mensagens enviadas via função mail() do PHP não é garantida. Além disso, você não receberá mensagens de bounce-back, em caso de falha na entrega.

Enviar emails usando SMTP

Agora, vou mostrar como usar o PHPMailer com o SMTP do Mailtrap Email Sending, pois ele oferece taxas de entregabilidade mais altas do que outras opções e é super fácil de configurar.

A primeira coisa que você precisa fazer é registrar uma conta e verificar seu domínio de envio de emails conforme descrito no vídeo abaixo:

Em seguida, encontre as credenciais SMTP fornecidas pelo Mailtrap na seção Sending Domains, na aba SMTP/API Settings.

A screenshot depicing Mailtrap Email Sending SMTP/API Settings and Transactional Stream.

Importante: Escolha o Transactional Stream por enquanto; abordarei o Bulk Stream mais tarde no artigo.

Agora, tudo o que você precisa fazer é usar o seguinte script para enviar um email em texto simples e inserir suas credenciais nele:

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php'; // Ajuste conforme o método de instalação

$mail = new PHPMailer(true); // Habilitar exceções

// Configuração SMTP
$mail->isSMTP();
$mail->Host = 'live.smtp.mailtrap.io'; // Seu servidor SMTP
$mail->SMTPAuth = true;
$mail->Username = 'your_username'; // Seu username Mailtrap
$mail->Password = 'your_password'; // Sua senha Mailtrap
$mail->SMTPSecure = 'tls';
$mail->Port = 2525;

// Configurações do remetente e destinatário
$mail->setFrom('from@example.com', 'From Name');
$mail->addAddress('recipient@example.com', 'Recipient Name');

// Enviando email em texto simples
$mail->isHTML(false); // Definir formato do email para texto simples
$mail->Subject = 'Seu Assunto Aqui';
$mail->Body    = 'Este é o corpo da mensagem de texto simples';

// Enviar o email
if(!$mail->send()){
    echo 'Message could not be sent. Mailer Error: ' . $mail->ErrorInfo;
} else {
    echo 'Message has been sent';
}

Não se esqueça de garantir que o método isHTML está configurado como “false” se você quiser enviar emails em texto simples.

Enviar emails HTML

Conheça mais sobre a personalização de emails HTML em PHP conferindo nosso artigo dedicado.

Para enviar uma mensagem HTML básica com o PHPMailer, basta garantir que a propriedade isHTML esteja configurada como (true) e podemos enviá-la assim:

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'path/to/composer/vendor/autoload.php'; // Garantir que o caminho está correto


$mail = new PHPMailer(true); // Passar `true` habilita exceções

try {
    $mail->isSMTP();
    $mail->Host = 'live.smtp.mailtrap.io';
    $mail->SMTPAuth = true;
    $mail->Username = 'paste one generated by Mailtrap'; // Seu username Mailtrap
    $mail->Password = 'paste one generated by Mailtrap'; // Sua senha Mailtrap
    $mail->SMTPSecure = 'tls';
    $mail->Port = 2525;

    $mail->setFrom('from@example.com', 'First Last');
    $mail->addReplyTo('towho@example.com', 'John Doe'); // 
    $mail->addAddress('recipient@example.com', 'Recipient Name'); // Adicionar um destinatário

    $mail->isHTML(true); // Definir formato do email para HTML
    $mail->Subject = "Teste de SMTP PHPMailer";
    $mail->Body = '<h1>Enviar email HTML em PHP usando SMTP.</h1><p>Este é um email de teste que envio, usando o servidor de email SMTP com o PHPMailer.</p>'; // Exemplo de corpo HTML
    $mail->AltBody = 'Esta é a versão do conteúdo do email em texto simples';

    if(!$mail->send()){
        echo 'Message could not be sent.';
        echo 'Mailer Error: ' . $mail->ErrorInfo;
    } else {
        echo 'Message has been sent';
    }
} catch (Exception $e) {
    echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}

Enviar emails para vários destinatários

Para enviar email para vários destinatários, tudo o que você precisa fazer é chamar o método addAddress() para cada destinatário.

Aqui está um trecho de código para enviar um email em HTML e em texto simples para vários destinatários:

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'path/to/composer/vendor/autoload.php';

$mail = new PHPMailer(true); // Habilitar exceções
$mail->isSMTP();
$mail->Host = 'sandbox.smtp.mailtrap.io';
$mail->SMTPAuth = true;
$mail->Username = '1a2b3c4d5e6f7g'; // Seu username Mailtrap
$mail->Password = '1a2b3c4d5e6f7g'; // Sua senha Mailtrap
$mail->SMTPSecure = 'tls';
$mail->Port = 2525;
$mail->SMTPKeepAlive = true; // Manter a conexão SMTP aberta após cada email enviado

$mail->setFrom('list@example.com', 'List Manager');
$mail->Subject = "New Mailtrap Mailing List";

$users = [
  ['email' => 'max@example.com', 'name' => 'Max'],
  ['email' => 'bob@example.com', 'name' => 'Bob']
];

foreach ($users as $user) {
  $mail->addAddress($user['email'], $user['name']); // Adicione o email de cada usuário corretamente
  $mail->Body = "<h2>Oi, {$user['name']}!</h2> <p>Como está?</p>";
  $mail->AltBody = "Oi, {$user['name']}! \nComo está?";

  try {
      if ($mail->send()) {
          echo "Message sent to: {$user['email']}\n";
      } else {
          echo "Mailer Error ({$user['email']}): {$mail->ErrorInfo}\n";
      }
  } catch (Exception $e) {
      echo "Mailer Error ({$user['email']}): {$e->getMessage()}\n";
  }
  $mail->clearAddresses(); // Limpar endereços para a próxima iteração
}

$mail->smtpClose(); // Opcionalmente, feche a conexão SMTP

Pro tip:

  • Você também pode usar addCC() e addBCC() para adicionar destinatários como cópias (CC) e cópias ocultas (BCC), respectivamente.

Enviar emails com anexos

Quando se trata de enviar anexos com PHPMailer, você tem duas opções:

  • Anexar um arquivo do seu filesystem

Com esta opção, você deve salvar seus arquivos no mesmo diretório que o script.

Para anexar um arquivo, tudo o que você precisa fazer é especificar o caminho. Além disso, você pode adicionar um nome de arquivo, mas isso é opcional, pois o script usará o nome real do seu arquivo:

$mail->addAttachment('path/to/invoice1.pdf', 'invoice1.pdf');

Portanto, por exemplo, quando você chamar este script, o PHPMailer anexará o ficheiro localizado em path/to/invoice1.pdf ao email. O segundo parâmetro, invoice1.pdf, é opcional e especifica o nome do arquivo conforme ele aparecerá para o destinatário. Se você não o incluir, o PHPMailer usará o nome original do arquivo.

Se você quiser adicionar outro arquivo, repita o comando:

$mail->addAttachment('path/to/calculation1.xlsx', 'calculation1.xlsx');
  • Adicionar um anexo de string

Este método permite anexar dados sem primeiro ter que salvá-los como um arquivo físico no seu filesystem. Essencialmente, você anexa os dados armazenados em uma variável. Por exemplo, se extrair um arquivo de um banco de dados, como um BLOB (Binary Large Object), você não precisa salvá-lo como um arquivo.

Para fazer isso, use o comando addStringAttachment(), que passará o conteúdo e o nome do arquivo:

$mysql_data = $mysql_row['blob_data'];
$mail->addStringAttachment($mysql_data, 'db_data.db'); 

Este é um exemplo de como adicionar dados armazenados como BLOB a partir de um banco de dados MySQL.

Você também pode usar um URL remoto, assim:

$mail->addStringAttachment(file_get_contents($url), 'myfile.pdf');

Enviar emails com imagem incorporada

Para enviar um email com uma imagem incorporada, eu uso anexos CID, assim:

$mail->addEmbeddedImage('path/to/image_file.jpg', 'image_cid');
$mail->isHTML(true);
$mail->Body = '<img src="cid:image_cid">';

E aqui está um exemplo completo de trecho de código para te dar uma ideia melhor:

<?php
use PHPMailer\PHPMailer\PHPMailer;
require 'path/to/composer/vendor/autoload.php';

$mail = new PHPMailer(true); // Habilitar exceções

$mail->isSMTP();
$mail->Host = 'live.smtp.mailtrap.io';
$mail->SMTPAuth = true;
$mail->Username = 'cole um gerado pelo Mailtrap';
$mail->Password = 'cole um gerado pelo Mailtrap';
$mail->SMTPSecure = 'tls';
$mail->Port = 2525;

$mail->setFrom('from@example.com', 'First Last');
$mail->addReplyTo('towho@example.com', 'John Doe');
$mail->addAddress('recipient@example.com', 'Recipient Name'); // Especificar o destinatário

$mail->isHTML(true);
$mail->Subject = "PHPMailer SMTP test";
$mail->addEmbeddedImage('path/to/image_file.jpg', 'image_cid'); // Especificar o caminho para sua imagem e um CID
$mail->Body = '<img src="cid:image_cid"> Mail body in HTML'; // Usar o CID como o atributo src na sua tag img
$mail->AltBody = 'Esta é a versão do conteúdo do email em texto simples';

if(!$mail->send()){
    echo 'Message could not be sent.';
    echo 'Mailer Error: ' . $mail->ErrorInfo;
}else{
    echo 'Message has been sent';
}

Envio assíncrono de emails

Embora o PHPMailer seja síncrono por natureza e não suporte operações assíncronas como Node.js, por exemplo, podemos usar a função exec() para chamar um script PHP que envia o email em segundo plano.

Para que este método funcione, você precisará instalar a CLI do PHP (Command Line Interface).

Aqui está o script sendEmail.php que você pode usar:

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'path/to/vendor/autoload.php'; // Ajuste o caminho conforme necessário

$mail = new PHPMailer(true);

// SMTP Configuration
$mail->isSMTP();
$mail->Host = 'smtp.example.com'; // Especifique os servidores SMTP principais e de backup
$mail->SMTPAuth = true; // Habilitar autenticação SMTP
$mail->Username = 'user@example.com'; // Nome de usuário SMTP
$mail->Password = 'secret'; // Senha SMTP
$mail->SMTPSecure = 'tls'; // Habilitar criptografia TLS, `ssl` também aceito
$mail->Port = 587; // Porta TCP para se conectar

// Definições de email
$mail->setFrom('from@example.com', 'Mailer');
$mail->addAddress('recipient@example.com', 'Recipient Name'); // Adicione um destinatário
$mail->isHTML(true); // Definir formato do email para HTML
$mail->Subject = 'Aqui está o assunto';
$mail->Body    = 'Este é o corpo HTML da mensagem <b>a negrito!</b>';
$mail->AltBody = 'Este é o corpo da mensagem em texto simples para provedores de email sem HTML';

try {
    $mail->send();
    echo 'Message has been sent';
} catch (Exception $e) {
    echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}

Para executar este script, use o seguinte comando:

exec("php /Absolute/path/to/sendEmail.php > /dev/null &");

Notas:

  • Você precisa garantir que o caminho para o executável da CLI do PHP (php) esteja corretamente especificado.
    • Em alguns casos e ambientes, pode ser necessário usar o caminho completo para o binário da CLI (por exemplo, /usr/bin/php).
  • Não se esqueça de verificar a configuração do PHP no seu servidor para garantir que funções como exec() não estejam desativadas, pois muitas vezes estão em ambientes de hosting compartilhado por razões de segurança.
    • A diretiva que controla isso é a disable_functions na php.ini.

Como enviar emails em massa

Até agora, usamos o Transactional Stream do Mailtrap, mas agora usaremos as credenciais do Bulk Stream, que permitem enviar emails para vários destinatários em simultâneo.

Então, faça login na sua conta Mailtrap e navegue até a aba SMTP Settings, onde você pode encontrar as credenciais do Bulk Stream no lado direito da janela.

A screenshot of Mailtrap Bulk Stream SMTP credentials.

Em seguida, insira essas credenciais no seguinte script, que você pode usar para enviar emails em massa:

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php'; // Caminho para o ficheiro autoload do Composer

$mail = new PHPMailer(true);

try {
    // Definições do servidor
    $mail->isSMTP();
    $mail->Host       = 'bulk.smtp.mailtrap.io'; // Definir o servidor SMTP para enviar
    $mail->SMTPAuth   = true;               // Habilitar autenticação SMTP
    $mail->Username   = 'your_smtp_username'; // Nome de usuário SMTP
    $mail->Password   = 'your_smtp_password'; // Senha SMTP
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Habilitar criptografia TLS; 
    $mail->Port       = 587; // Porta TCP à qual se conectará

    // Endereço do remetente e de resposta
    $mail->setFrom('from@example.com', 'Mailer');
    $mail->addReplyTo('replyto@example.com', 'Mailer');

    // Conteúdo
    $mail->isHTML(true); // Definir formato do email para HTML
    
    // Lista de destinatários
    $recipients = [
        ['email' => 'person1@example.com', 'name' => 'Person One'],
        ['email' => 'person2@example.com', 'name' => 'Person Two'],
        // Adicionar mais destinatários conforme necessário
    ];

    foreach ($recipients as $recipient) {
        $mail->addAddress($recipient['email'], $recipient['name']); // Adicionar um destinatário

        // Personalizar a message
        $mail->Subject = 'Aqui está o assunto';
        $mail->Body    = 'Este é o corpo HTML da mensagem <b>a negrito!</b>';
        $mail->AltBody = 'Este é o corpo da mensagem em texto simples para provedores de email sem HTML';

        $mail->send();
        $mail->clearAddresses(); // Clear addresses for the next iteration
    }

    echo 'Messages have been sent';
} catch (Exception $e) {
    echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}

Dessa forma, podemos enviar emails para vários destinatários sem abrir e fechar a conexão SMTP para cada email. É mais eficiente do que, digamos, criar uma nova instância do PHPMailer para cada email.

Mas, se você estiver lidando com um grande volume de emails, pode usar um sistema para colocar jobs em fila de espera, como RabbitMQ, Beanstalkd, Redis, etc.

Para o exemplo, vou mostrar como fazer isso com Redis.

Primeiro, vamos instalar um cliente PHP para Redis, predis/predis, via Composer, executando o seguinte comando no diretório raiz do projeto, onde seu arquivo composer.json está localizado:

composer require predis/predis

Em seguida, precisaremos de um script produtor de tarefas que empurrará tarefas de email para uma lista Redis. Observe que, aqui, cada tarefa pode ser uma string codificada em JSON, com todos os dados necessários para enviar um email:

require 'vendor/autoload.php';

use Predis\Client;

$redis = new Client();

while (true) {
    //  Tente retirar um job ou tarefa da lista 'emailQueue', bloqueie por até 5 segundos se estiver vazia
    $job = $redis->brpop(['emailQueue'], 5);

    if ($job) {
        // Formato da tarefa: [$listName, $jobData]
        $emailDataJson = $job[1];
        $emailData = json_decode($emailDataJson, true);

        // Processar os dados do email...
        // Enviar o email com PHPMailer, registrar sucesso/falha, etc.

        echo "Processed a job from emailQueue: " . $emailDataJson . "\n";
    } else {
        // Nenhuma tarefa estava disponível na fila dentro do período de tempo em timeout
        echo "Waiting for jobs...\n";
    }
}

Por fim, vamos criar um script de trabalhador e garantir que o PHPMailer esteja configurado com as credenciais do Bulk Stream:

<?php
require 'vendor/autoload.php';

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use Predis\Client;

// Inicializar o cliente Redis
$redis = new Client();

// Função logger
function logError($message) {
    // Adicionar erros a um arquivo de log
    file_put_contents('email_errors.log', $message . PHP_EOL, FILE_APPEND);
}

// Função para enviar email, retorna true em caso de sucesso ou false em caso de falha
function sendEmail($emailData) {
    $mail = new PHPMailer(true);

    try {
        // Configuração SMTP
        $mail->isSMTP();
        $mail->Host       = 'bulk.smtp.mailtrap.io';
        $mail->SMTPAuth   = true;
        $mail->Username   = 'seu_nome_de_usuário_smtp';
        $mail->Password   = 'sua_senha_smtp';
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        $mail->Port       = 587;

        // Destinatários
        $mail->setFrom('from@example.com', 'Mailer');
        $mail->addAddress($emailData['email']); // Recipient

        // Conteúdo
        $mail->isHTML(true); // Formato do email para HTML
        $mail->Subject = $emailData['subject'];
        $mail->Body    = $emailData['body'];

        $mail->send();
        return true;
    } catch (Exception $e) {
        // Registra o erro específico
        logError("Email could not be sent to {$emailData['email']}. Mailer Error: " . $mail->ErrorInfo);
        return false;
    }
}

// Política de segundas tentativas
$maxRetries = 3; // Número máximo de segundas tentativas para uma tentativa de envio de email falhada
$retryDelay = 2; // Atraso inicial entre as segundas tentativas, em segundos

while ($emailDataJson = $redis->rpop('emailQueue')) {
    $emailData = json_decode($emailDataJson, true);
    $attempt = 0;

    while (!sendEmail($emailData) && $attempt < $maxRetries) {
        $attempt++;
        // Backoff exponencial
        sleep($retryDelay * pow(2, $attempt - 1));
    }

    if ($attempt == $maxRetries) {
        // Registro final para emails que falharam após todas as segundas tentativas
        logError("Final failure: Email could not be sent to {$emailData['email']} after $maxRetries attempts.");
    } else {
        echo "Email sent to {$emailData['email']}\n";
    }
}

Pro tip: Se você optar pelo Redis, recomendo usar um gerenciador de processos como Supervisor, que manterá o script do worker em execução e o reiniciará automaticamente se ele falhar.

Enviar emails usando API

A melhor maneira de enviar emails com base em API é usar o SDK oficial do provedor de serviços de email em PHP, pois o PHPMailer não foi projetado para esse propósito. Felizmente, podemos contar com a API de envio de email do Mailtrap: a Email Sending API, que oferece um cliente PHP e permite integrar facilmente o Mailtrap ao seu aplicativo.

Para começar a enviar emails com a Mailtrap Email Sending API, você precisa primeiro criar uma conta e, em seguida, adicionar e verificar seu domínio.

Depois, instale o SDK oficial do Mailtrap PHP via Composer.

Você pode usar um dos seguintes comandos para começar rapidamente:

# Com cliente http symfony (recomendado)
composer require railsware/mailtrap-php symfony/http-client nyholm/psr7

# Ou com cliente http guzzle
composer require railsware/mailtrap-php guzzlehttp/guzzle php-http/guzzle7-adapter

Nota: Como o Cliente de API Mailtrap usa a abstração do cliente PSR-18 e, portanto, não é rigidamente acoplado a nenhuma biblioteca que envia mensagens HTTP, ele oferece a flexibilidade de escolher qual cliente HTTP você deseja usar.

E para enviar um email em texto simples com o SDK, basta usar o trecho de código abaixo:

<?php

use Mailtrap\Config;
use Mailtrap\EmailHeader\CategoryHeader;
use Mailtrap\EmailHeader\CustomVariableHeader;
use Mailtrap\Helper\ResponseHelper;
use Mailtrap\MailtrapClient;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Header\UnstructuredHeader;

require __DIR__ . '/vendor/autoload.php';

// Seu token de API token daqui https://mailtrap.io/api-tokens
$apiKey = getenv('MAILTRAP_API_KEY');
$mailtrap = new MailtrapClient(new Config($apiKey));

$email = (new Email())
    ->from(new Address('example@your-domain-here.com', 'Mailtrap Test'))
    ->replyTo(new Address('reply@your-domain-here.com'))
    ->to(new Address('email@example.com', 'Jon')) // Destinatário único
    ->priority(Email::PRIORITY_HIGH)
    ->subject('Dicas para criar emails HTML')
    ->text('Oi! Aprenda as melhores práticas para criar emails em HTML e experimente templates prontos a utilizar. O guia do Mailtrap sobre Como Criar Emails em HTML já está no nosso blog');

// Cabeçalhos
$email->getHeaders()
    ->addTextHeader('X-Message-Source', 'domain.com')
    ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client')); // o mesmo que addTextHeader

// Variáveis personalizadas
$email->getHeaders()
    ->add(new CustomVariableHeader('user_id', '45982'))
    ->add(new CustomVariableHeader('batch_id', 'PSJ-12'));

// Categoria (deve ser apenas uma)
$email->getHeaders()
    ->add(new CategoryHeader('Integration Test'));

try {
    $response = $mailtrap->sending()->emails()->send($email); // API de envio de emails (real)
    
    var_dump(ResponseHelper::toArray($response)); // corpo (array)
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

Nota:

  • Certifique-se de copiar e colar seu token de API no script, que você pode encontrar na aba SMTP/API Settings na seção Sending Domains.

Enviar emails HTML

Para enviar email HTML, basta modificar o script para emails em texto simples, adicionando o método ->html().

No exemplo de código abaixo, vou mostrar como enviar um email HTML que você pode enviar para vários destinatários e anexar arquivos a ele:

<?php

use Mailtrap\Config;
use Mailtrap\EmailHeader\CategoryHeader;
use Mailtrap\EmailHeader\CustomVariableHeader;
use Mailtrap\Helper\ResponseHelper;
use Mailtrap\MailtrapClient;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Header\UnstructuredHeader;
use Symfony\Component\Mime\Part\DataPart;

require __DIR__ . '/vendor/autoload.php';

// Seu token de API daqui https://mailtrap.io/api-tokens


$apiKey = “MAILTRAP_API_KEY”;
$mailtrap = new MailtrapClient(new Config($apiKey));

$email = (new Email())
    ->from(new Address('example@your-domain-here.com', 'Mailtrap Test'))
    ->replyTo(new Address('reply@your-domain-here.com'))
    ->to(new Address('email@example.com', 'Jon'))
    ->priority(Email::PRIORITY_HIGH)
    ->cc('mailtrapqa@example.com')
    ->addCc('staging@example.com')
    ->bcc('mailtrapdev@example.com')
    ->subject('Dicas para criar emails HTML')
    ->text('Oi! Aprenda as melhores práticas para criar emails em HTML e experimente templates prontos a utilizar. O guia do Mailtrap sobre Como Criar Emails em HTML já está no nosso blog')
    ->html(
        '<html>
        <body>
        <p><br>Oi</br>
        Aprenda as melhores práticas para criar emails em HTML e experimente templates prontos a utilizar.</p>
        <p><a href="https://mailtrap.io/blog/build-html-email/">O guia do Mailtrap sobre Como Criar Emails em HTML</a> já está no nosso blog</p>
        <img src="cid:logo">
        </body>
    </html>'
    )
    ->embed(fopen('https://mailtrap.io/wp-content/uploads/2021/04/mailtrap-new-logo.svg', 'r'), 'logo', 'image/svg+xml');

// Adicionar anexo
$email->attachFromPath('/path/to/your/file.pdf', 'Filename.pdf', 'application/pdf');

// Cabeçalhos
$email->getHeaders()
    ->addTextHeader('X-Message-Source', 'domain.com')
    ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client')); // the same as addTextHeader

// Variáveis Personalizáveis
$email->getHeaders()
    ->add(new CustomVariableHeader('user_id', '45982'))
    ->add(new CustomVariableHeader('batch_id', 'PSJ-12'));

// Categoria (deve ser apenas uma)
$email->getHeaders()
    ->add(new CategoryHeader('Integration Test'));

try {
    $response = $mailtrap->sending()->emails()->send($email); // API de envio de email (real)
    
    var_dump(ResponseHelper::toArray($response)); // corpo (array)
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

Enviar emails para vários destinatários

Para enviar um email para vários destinatários, basta adicionar os endereços aos campos to, cc e bcc do código. A classe Symfony Email, usada no script, permite adicionar vários destinatários em cada um dos campos.

Aqui está um exemplo de um código que você pode usar:

<?php

use Mailtrap\Config;
use Mailtrap\EmailHeader\CategoryHeader;
use Mailtrap\EmailHeader\CustomVariableHeader;
use Mailtrap\Helper\ResponseHelper;
use Mailtrap\MailtrapClient;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Header\UnstructuredHeader;

require __DIR__ . '/vendor/autoload.php';

// Seu token de API daqui https://mailtrap.io/api-tokens
$apiKey = getenv('MAILTRAP_API_KEY');
$mailtrap = new MailtrapClient(new Config($apiKey));

$email = (new Email())
    ->from(new Address('example@your-domain-here.com', 'Mailtrap Test'))
    ->replyTo(new Address('reply@your-domain-here.com'))
    ->to(new Address('email@example.com', 'Jon'))
    ->priority(Email::PRIORITY_HIGH)
    ->cc('mailtrapqa@example.com')
    ->addCc('staging@example.com')
    ->bcc('mailtrapdev@example.com')
    ->subject('Dicas para criar emails HTML’)
    ->text('Oi! Aprenda as melhores práticas para criar emails em HTML e experimente templates prontos a utilizar. O guia do Mailtrap sobre Como Criar Emails em HTML já está no nosso blog');

// Cabeçalhos
$email->getHeaders()
    ->addTextHeader('X-Message-Source', 'domain.com')
    ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client')); // o mesmo que addTextHeader

// Variáveis personalizadas
$email->getHeaders()
    ->add(new CustomVariableHeader('user_id', '45982'))
    ->add(new CustomVariableHeader('batch_id', 'PSJ-12'));

// Categoria (deve ser apenas uma)
$email->getHeaders()
    ->add(new CategoryHeader('Integration Test'));

try {
    $response = $mailtrap->sending()->emails()->send($email); // API de envio de emails (real)
    
    var_dump(ResponseHelper::toArray($response)); // corpo (array)
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

Enviar emails com anexos

Para enviar um email com anexos, podemos usar o método attachFromPath() fornecido pela classe Symfony Mime Email. Ele permite anexar um arquivo especificando o caminho para o arquivo.

Você pode usar o código a seguir para enviar um email com arquivos anexados:

<?php

use Mailtrap\Config;
use Mailtrap\EmailHeader\CategoryHeader;
use Mailtrap\EmailHeader\CustomVariableHeader;
use Mailtrap\Helper\ResponseHelper;
use Mailtrap\MailtrapClient;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Header\UnstructuredHeader;

require __DIR__ . '/vendor/autoload.php';

// Seu token de API daqui https://mailtrap.io/api-tokens


$apiKey = “MAILTRAP_API_KEY”;
$mailtrap = new MailtrapClient(new Config($apiKey));

// Inicializar o objeto de email
$email = (new Email())
    ->from(new Address('example@your-domain-here.com', 'Mailtrap Test'))
    ->replyTo(new Address('reply@your-domain-here.com'))
    ->to(new Address('email@example.com', 'Jon')) // Para vários destinatários, repita esta linha com endereços diferentes
    ->priority(Email::PRIORITY_HIGH)
    ->subject('Dicas para criar emails HTML')
    ->text("Oi! Aprenda as melhores práticas para criar emails em HTML e experimente templates prontos a utilizar. O guia do Mailtrap sobre Como Criar Emails em HTML já está no nosso blog”);

// Anexar um arquivo
$email->attachFromPath('/path/to/your/file.pdf', 'filename.pdf', 'application/pdf');

// Cabeçalhos e Variáveis Personalizadas conforme definido anteriormente
$email->getHeaders()
    ->addTextHeader('X-Message-Source', 'domain.com')
    ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client'))
    ->add(new CustomVariableHeader('user_id', '45982'))
    ->add(new CustomVariableHeader('batch_id', 'PSJ-12'))
    ->add(new CategoryHeader('Integration Test'));

try {
    $response = $mailtrap->sending()->emails()->send($email); // Enviar o email pelo Mailtrap
    var_dump(ResponseHelper::toArray($response)); // Exibir a resposta
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

Enviar emails com uma imagem incorporada

Enviar emails com uma imagem incorporada também é muito fácil, pois podemos usar o método ->embed() como parte do objeto Email. O método essencialmente nos permite incluir imagens diretamente no corpo HTML do email, que podem ser referenciadas por meio de um Content-ID (CID).

<?php

use Mailtrap\Config;
use Mailtrap\EmailHeader\CategoryHeader;
use Mailtrap\EmailHeader\CustomVariableHeader;
use Mailtrap\Helper\ResponseHelper;
use Mailtrap\MailtrapClient;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Header\UnstructuredHeader;

require __DIR__ . '/vendor/autoload.php';

// Seu token de API daqui https://mailtrap.io/api-tokens
$apiKey = getenv('MAILTRAP_API_KEY');
$mailtrap = new MailtrapClient(new Config($apiKey));

// Inicializar o objeto de email com os detalhes necessários
$email = (new Email())
    ->from(new Address('example@your-domain-here.com', 'Mailtrap Test'))
    ->replyTo(new Address('reply@your-domain-here.com'))
    ->to(new Address('email@example.com', 'Recipient Name'))
    ->subject('Email HTML com uma Imagem Incorporada')
    ->html('<html><body>Here is an embedded image: <img src="cid:unique-image-id"></body></html>');

// Incorporar a imagem e atribuir um CID
$imagePath = '/path/to/your/image.jpg'; // Certifique-se de usar o caminho correto para o seu arquivo de imagem
$email->embedFromPath($imagePath, 'unique-image-id');

// (Opcional) Adicionar configurações adicionais como CC, BCC, parte de texto, etc.

try {
    $response = $mailtrap->sending()->emails()->send($email); // Enviar o email pelo Mailtrap
    var_dump(ResponseHelper::toArray($response)); // Exibir a resposta
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

Nota: Não se esqueça de substituir /path/to/your/image.jpg pelo caminho real do seu arquivo de imagem.

Envio assíncrono de emails

Para enviar solicitações HTTP de forma assíncrona, você pode usar as funções curl_multi do PHP.

A função curl_multi_init() faz parte da extensão cURL, que permite fazer várias solicitações HTTP simultaneamente, mas se essa extensão não estiver habilitada ou instalada, você não poderá usá-la ou qualquer outra função cURL.

Para resolver esse problema, você precisa habilitar a extensão cURL na sua instalação do PHP. Aqui estão os passos para fazer isso em diferentes sistemas operacionais:

sudo apt-get update
sudo apt-get install php-curl

Após a instalação, pode ser necessário habilitar a extensão manualmente editando seu arquivo php.ini, embora geralmente seja habilitada automaticamente. Se necessário, procure seu arquivo php.ini (o local depende da sua versão do PHP e configuração, um caminho comum pode ser /etc/php/7.4/cli/php.ini para PHP 7.4 CLI) e certifique-se de que a linha extension=curl está sem comentários (remova o ponto e vírgula no início da linha, se existir).

Você precisa reiniciar o servidor Apache.

sudo service apache2 restart

Aqui está um exemplo de código de como você pode fazer isso:

<?php

// Inicializar o manipulador cURL multi
$multiCurl = curl_multi_init();

// Array para acompanhar os manipuladores cURL individuais
$curlHandles = [];

// Exemplo: Vários dados de email (para demonstração, enviando o mesmo email para vários destinatários)
$emailDatas = [
    [
        'from' => 'from@example.com',
        'to' => 'recipient1@example.com',
        'subject' => 'Aqui está o assunto',
        'text' => 'Este é o corpo da mensagem em texto simples',
        'html' => '<p>Este é o corpo da mensagem em HTML</p>',
    ],
    [
        'from' => 'from@example.com',
        'to' => 'recipient2@example.com',
        'subject' => 'Aqui está o assunto',
        'text' => 'Este é o corpo da mensagem em texto simples',
        'html' => '<p>Este é o corpo da mensagem em HTML</p>',
    ]
    // Adicionar mais conforme necessário
];

foreach ($emailDatas as $emailData) {
    // Preparar o manipulador cURL para cada email
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://api.mailtrap.io/v1/messages'); // Use o endpoint correto da API
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($emailData));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json',
        'Authorization: Bearer your_mailtrap_api_token', // Use seu token de API do Mailtrap real
    ]);

    // Adicionar o manipulador cURL ao manipulador multi
    curl_multi_add_handle($multiCurl, $ch);
    $curlHandles[] = $ch; // Acompanhar os manipuladores
}

// Executar o manipulador cURL multi
$active = null;
do {
    $mrc = curl_multi_exec($multiCurl, $active);
    if ($mrc != CURLM_OK) {
        // Tratar o erro cURL multi
        break;
    }
    // Esperar por atividade em qualquer conexão curl_multi
    if (curl_multi_select($multiCurl) == -1) {
        usleep(100);
    }
} while ($active);

// Ler e processar as respostas
foreach ($curlHandles as $handle) {
    $response = curl_multi_getcontent($handle);
    // Processar sua resposta aqui. Verificar código de status HTTP, corpo da resposta, etc.
    echo $response . PHP_EOL;

    // Remover e fechar o manipulador
    curl_multi_remove_handle($multiCurl, $handle);
    curl_close($handle);
}

// Fechar o manipulador cURL multi
curl_multi_close($multiCurl);

Como enviar emails em massa

Se você planeja enviar grandes quantidades de email em PHP com a API de envio de email do Mailtrap, sua melhor aposta seria usar um sistema de fila de tarefas ou jobs.

Mas primeiro, precisamos configurar nosso Bulk Stream. Então, navegue até a aba SMTP/API Settings na sua conta Mailtrap e selecione API na janela Bulk Stream. Lá, você pode encontrar o host e o Token de API, que você precisa copiar e colar no seu script PHP.

Mailtrap API Bulk Stream Settings

Com essas credenciais do Bulk Stream configuradas assim, você pode usar praticamente qualquer sistema de fila de tarefas, como RabbitMQ, Beanstalkd, etc. Para os fins deste tutorial, vou mostrar como configurar o Redis.

Se você ainda não fez isso, adicione o Redis ao seu projeto:

composer require predis/predis

Para enfileirar uma tarefa no Redis com todas as informações necessárias, use o seguinte trecho de código PHP:

require 'vendor/autoload.php';

$predis = new Predis\Client();

$emailData = [
    'from' => 'from@example.com',
    'to' => 'recipient@example.com',
    'subject' => 'Your Subject Here',
    'html' => '<p>Your HTML content here</p>',
    'text' => 'Your plain text here',
    // Incluir quaisquer outros dados necessários para o email
];

// Enfileirar os dados do email para processamento posterior
$predis->lpush('emailQueue', json_encode($emailData));

Por fim, use este script PHP que monitora continuamente a fila Redis para novas tarefas de email, as limpa da fila e as envia através da Email Sending API do Mailtrap:

require 'vendor/autoload.php';

$predis = new Predis\Client();
$mailtrapConfig = new Mailtrap\Config('your_mailtrap_api_key');
$mailtrapClient = new Mailtrap\MailtrapClient($mailtrapConfig);

while (true) {
    // Bloquear até que uma tarefa de email esteja disponível
    $emailTask = $predis->brpop('emailQueue', 0);
    
    if ($emailTask) {
        $emailData = json_decode($emailTask[1], true); // $emailTask[1] contém os dados de email
        
        // Enviar o email usando a Email Sending API do Mailtrap
        $email = (new Symfony\Component\Mime\Email())
            ->from(new Address($emailData['from']))
            ->to(new Address($emailData['to']))
            ->subject($emailData['subject'])
            ->html($emailData['html'])
            ->text($emailData['text']);
        
        try {
            $response = $mailtrapClient->sending()->emails()->send($email);
            echo "Email sent: ", var_dump($response), "\n";
        } catch (Exception $e) {
            echo "Failed to send email: ", $e->getMessage(), "\n";
        }
    }
}

E não se esqueça de executar este worker como um processo em segundo plano ou como uma tarefa em um gerenciador de processos, como o Supervisor.

Teste emails antes de os enviar

Até agora, descrevi várias maneiras de enviar emails em PHP, mas como saber se a funcionalidade de envio de emails faz o seu trabalho como pretendido? Com todo esse código implementado, é crucial testar seus emails em PHP antes de enviá-los, independentemente do método de envio que você escolher.

Testar seus emails é o padrão da indústria e é uma etapa crítica do ciclo de envio de emails. Felizmente, temos tudo o que você precisa com a solução holística de Email Testing do Mailtrap.

Com o Mailtrap Email Testing, você pode verificar, pré-visualizar e solucionar problemas em seus emails antes de enviá-los. Essencialmente, você pode inspecionar o HTML/CSS do seu email e facilmente identificar linhas de código com falhas e corrigi-las ou removê-las.

Mailtrap HTML Check

Esta funcionalidade é crucial para verificar a compatibilidade dos seus designs baseados em HTML/CSS e polir os mesmos à perfeição, sem se preocupar em enviar o email em tempo real.

Você também pode compartilhar seu processo de teste com os membros da sua equipe, criar novos projetos, adicionar outros projetos dentro deles, e muito mais com o Mailtrap Email Testing.

Mailtrap Projects

Mais importante ainda, configurar o Mailtrap Email Testing é super fácil, pois pode ser facilmente integrada via credenciais SMTP ou pelo SDK oficial PHP.

SMTP

Para testar seus emails com um servidor SMTP falso, basta especificar as credenciais SMTP do Mailtrap no seu método de transporte:

Host: sandbox.smtp.mailtrap.io
Port: 25 or 465 or 587 or 2525
Username: exclusivo para cada caixa de entrada do Mailtrap
Password: exclusiva para cada caixa de entrada do Mailtrap
TLS: Opcional (STARTTLS em todas as portas)

Você também pode integrar o Mailtrap com várias bibliotecas e frameworks PHP. Por exemplo, aqui está uma amostra de integração com PHPMailer:

$phpmailer = new PHPMailer();
$phpmailer->isSMTP();
$phpmailer->Host = 'sandbox.smtp.mailtrap.io';
$phpmailer->SMTPAuth = true;
$phpmailer->Port = 2525;
$phpmailer->Username = '1a2b3c4d5e6f7g';
$phpmailer->Password = '1a2b3c4d5e6f7g';

E aqui está como seu MAILER_DSN ficaria se você integrasse o Mailtrap com o framework Symfony, por exemplo:

MAILER_DSN=smtp://username:password@sandbox.smtp.mailtrap.io:2525/?encryption=tls

Uma vez que você enviar seu email de teste, você pode verificar a caixa de entrada virtual do Mailtrap após alguns momentos, e deverá ver a seguinte mensagem:

Mailtrap Email Testing HTML preview

API

Para integrar a API de Testes de Email do Mailtrap com seu aplicativo baseado em PHP, você pode usar o seguinte código:

?php

use Mailtrap\Config;
use Mailtrap\EmailHeader\CategoryHeader;
use Mailtrap\EmailHeader\CustomVariableHeader;
use Mailtrap\Helper\ResponseHelper;
use Mailtrap\MailtrapClient;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Header\UnstructuredHeader;

require __DIR__ . '/../vendor/autoload.php';


/**********************************************************************************************************************
 ******************************************* EMAIL TESTING ************************************************************
 **********************************************************************************************************************
 */

/**
 * Email Testing API
 *
 * POST https://sandbox.api.mailtrap.io/api/send/{inbox_id}
 */
try {
    // seu token de API daqui https://mailtrap.io/api-tokens
    $apiKey = getenv('MAILTRAP_API_KEY');
    $mailtrap = new MailtrapClient(new Config($apiKey));

    $email = (new Email())
        ->from(new Address('mailtrap@example.com', 'Mailtrap Test'))
        ->replyTo(new Address('reply@example.com'))
        ->to(new Address('email@example.com', 'Jon'))
        ->cc('mailtrapqa@example.com')
        ->addCc('staging@example.com')
        ->bcc('mailtrapdev@example.com')
        ->subject('Dicas para criar emails HTML')
        ->text('Oi! Aprenda as melhores práticas para criar emails em HTML e experimente templates prontos a utilizar. O guia do Mailtrap sobre Como Criar Emails em HTML já está no nosso blog')
        ->html(
            '<html>
            <body>
            <p><br>Oi</br>
            Aprenda as melhores práticas para criar emails em HTML e experimente templates prontos a utilizar.</p>
            <p><a href="https://mailtrap.io/blog/build-html-email/">O guia do Mailtrap sobre Como Criar Emails em HTML</a> já está no nosso blog.</p>
            <img src="cid:logo">
            </body>
        </html>'
        )
        ->embed(fopen('https://mailtrap.io/wp-content/uploads/2021/04/mailtrap-new-logo.svg', 'r'), 'logo', 'image/svg+xml')
        ->attachFromPath('README.md')
    ;

    // Cabeçalhos
    $email->getHeaders()
        ->addTextHeader('X-Message-Source', '1alf.com')
        ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client'))
    ;

    // Variáveis personalizadas
    $email->getHeaders()
        ->add(new CustomVariableHeader('user_id', '45982'))
        ->add(new CustomVariableHeader('batch_id', 'PSJ-12'))
    ;

    // Categoria (deve ser apenas uma)
    $email->getHeaders()
        ->add(new CategoryHeader('Integration Test'))
    ;

    // param -> inbox_id obrigatório
    $response = $mailtrap->sandbox()->emails()->send($email, 1000001); // <--- você deve usar seu inbox_id aqui (caso contrário, receberá 401)

    // imprimir todas as informações possíveis da resposta
    var_dump($response->getHeaders()); //cabeçalhos (array)
    var_dump($response->getStatusCode()); //código de status (int)
    var_dump(ResponseHelper::toArray($response)); // corpo (array)
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

E, claro, não se esqueça de substituir os valores de placeholder, como o token da API e outras credenciais, pelos dados reais fornecidos na sua conta Mailtrap.

Para mais informações sobre a API de Testes de Email do Mailtrap, suas funcionalidades e as várias operações que ela permite realizar (por exemplo, Testes, Automação de QA, testes de sequências automatizadas, etc.), consulte a documentação oficial.

Concluindo

E com isso, concluímos nosso tutorial sobre enviar email em PHP!

Cobri as opções de envio de email mais populares em PHP e descrevi como você pode fazer isso com um serviço de email de terceiros como o Mailtrap, que pode ajudá-lo a economizar tempo, dinheiro e esforço.

Se você estiver interessado em aprender mais, não deixe de conferir nosso blog onde você pode ler mais artigos relacionados a PHP, como:

Ivan Djuric, an author at Mailtrap
Article by Ivan Djuric Technical Content Writer @Mailtrap

I’m a Technical Content Writer with 5 years of background covering email-related topics in tight collaboration with software engineers and email marketers. I just love to research and share actionable insights with you about email sending, testing, deliverability improvements, and more. Happy to be your guide in the world of emails!

Article by Viktoriia Ivanenko Technical Content Writer @ Mailtrap

Experienced content and marketing specialist: content creation for the blog and video channel, UX/UI copies, technical writing, app localizations, and SEO. Skilled in marketing strategies, video production and management, creating brand concepts, technical and marketing writing, and analytical skills. Strong information technology professional of 10+ years work experience with a background from The University of Edinburgh, UK and Clark University, USA.