Ao utilizar a função mail do PHP, você pode se deparar com um inconveniente por causa de codificação de caracteres usada para o assunto ou o conteúdo do e-mail. O problema é que o protocolo SMTP só permite a transmissão de dados em US-ASCII. Para utilizar caracteres que não fazem parte da tabela US-ASCII, é preciso utilizar um mecanismo de codificação dos dados para que o resultado seja compatível com US-ASCII. Neste artigo, veremos como fazer isso e enviar e-mail com assunto e conteúdo corretamente.
Codificação do assunto
Para codificar o assunto de um e-mail, basta utilizar a expressão:
"=?charset?método?texto codificado?=
Em "charset", é colocada a codificação de caracteres do texto do assunto.
Em "método", é colocada a letra "B" para base64 ou "Q" para quoted-printable.
Em "texto codificado", é colocado o texto codificado do assunto, usando o método e charset definidos.
Veja um exemplo para montar o assunto com o método base64 a partir de um assunto em UTF-8:
$assunto = 'Açúcar possui acento'; $assunto_codificado = sprintf('=?%s?%s?%s?=', 'UTF-8', 'B', base64_encode($assunto));
Para usar o método quoted-printable, é preciso usar a função quoted_printable_encode, disponível a partir do PHP 5.3.0 ou imap_8bit, disponível na extensão IMAP. Este método deixa o conteúdo menor e mais legível, porém, depende da disponibilidade da função. A função base64_encode, por sua vez, está disponível desde o PHP 4. Veja um exemplo de codificação com quoted-printable:
$assunto = 'Açúcar possui acento'; $assunto_codificado = sprintf('=?%s?%s?%s?=', 'UTF-8', 'Q', quoted_printable_encode($assunto));
Depois, basta passar o parâmetro $subject da função mail com o valor codificado.
mail($destinatario, $assunto_codificado, $mensagem, $header)
Codificação do conteúdo
Para enviar o conteúdo do e-mail, também é utilizado um dos métodos de codificação. Porém, o método utilizado é especificado no cabeçalho do e-mail. Para especificar o cabeçalho, basta utilizar as diretivas:
- Content-Type - para definir o mime-type do conteúdo do e-mail e o charset.
- Content-Transfer-Encodding - para definir o método de codificação.
Neste caso, o conteúdo precisa de uma quebra de linha a cada 76 caracteres. As funções de codificação quoted-printable já fazem a quebra automática. A função base64_encode precisa de um auxilio da função chunk_split. Veja um exemplo de um e-mail com conteúdo textual enviado com codificação base64:
$conteudo = <<<TXT Conteúdo do e-mail. Blá blá blá. TXT; $conteudo_codificado = chunk_split(base64_encode($conteudo), 76, "\r\n"); $header = <<<HTTP Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: base64 Content-Disposition: inline From: {$remetente} To: {$destinatario} HTTP; mail($destinatario, $assunto_codificado, $conteudo_codificado, $header);
Extra
Além do assunto e do conteúdo do e-mail, também é possível codificar o nome do remetente e do destinatário do e-mail. É utilizado o mesmo mecanismo do assunto. Veja um exemplo para codificar o nome do destinatário do e-mail com base64:
$nome = 'Alguém com Acento no Nome'; $email = 'alguem@teste.com'; $destinatario = sprintf('=?%s?%s?%s?= <%s>', 'UTF-8', 'B', base64_encode($nome), $email);
6 comentários
Ótimo post.
Para funcionar eu tive que adicionar aos headers isso também:
"MIME-Version: 1.0\r\n"
Resolveu o problema do assunto :))
O e-mail estava com o corpo de texto na codificação correta, mas o assunto vinha errado.
Heheh Muito Obrigado!
Muito didático. Parabéns pelo artigo.
O corpo da mensagem fica desta forma "Q29udGXDumRvIGRvIGUtbWFpbC4KQmzDoSBibMOhIGJsw6Eu
" ao utilizar esta configuração; funcionou apenas para o assunto.
Fagner, certifique-se que passou o cabeçalho do e-mail corretamente, conforme mostrado no exemplo do artigo. Veja a linha:
Content-Transfer-Encoding: base64
Ela diz que o conteúdo do arquivo (que é o texto do e-mail) está em base64.
\n não funciona . ele nao quebra linha mais.
Postar um comentário
Nota: fique a vontade para expressar o que achou deste artigo ou do blog.
Dica: para acompanhar as respostas, acesse com uma conta do Google e marque a opção "Notifique-me".
Atenção: o blogger não permite inclusão de tags nos comentários, por isso, use algum site externo para postar seu código com dúvidas e deixe o link aqui. Exemplo: pastebin.com