PHP mail() function

Asked

Viewed 1,687 times

4

I am trying to send an email via PHP with HTML attributes, an email formatted with images and style="" or classes. I tried to use Phpmailer, but without success, so I resorted to the mail() function of PHP that meets my needs and sends the email without many problems, the only problem in itself is that the email is not authenticated and keeps falling into quarantine, Can I take any action to correct this? Another problem, my main is that email does not send when I try to put tags as <div style="text-align: center; margin: 0 auto;"></div> and also when I try to add images with <img src='http://meusite.com.br/templates-email/cabecalho.jpg' alt='img' /> (only one example).

The point is:

  1. How to send HTML emails using the mail() function (including images in this email and Divs). ?
  2. How to solve the problem of the authenticity of emails (they live in quarantine).

ATTEMPT 1 (does not send).

//envia e-mail de confirmação
    $email_remetente = "[email protected]";
    $headers = "MIME-Version: 1.1\n";
    $headers .= "Content-type: text/HTML; charset=utf-8\n";
    $headers .= "From: $email_remetente\n"; // remetente
    $headers .= "Return-Path: $email_remetente\n"; // return-path
    $headers .= "Reply-To: $email_usuario\n"; // Endereço (devidamente validado) que o seu usuário informou no contato
    $texto_mensagem = "<html><head><title>Blue Contract - Ative sua conta</title></head><body>";
    $texto_mensagem .= "<div style=\'font: 14px Arial, Tahoma; text-align: center; margin: 0 auto;\'>";
    $texto_mensagem .= "<img src='http://bluecontract.com.br/templates-email/cabecalho.jpg' alt='img' />";
    $texto_mensagem .= "<h1>Ativação de conta - Blue Contract</h1>";
    $texto_mensagem .= "<p>Através de nosso website, você efetuou um cadastro em ".$usuDataCadastro."</p>";
    $texto_mensagem .= "<p>Agora, para finalizar seu cadastro é necessário confirmar sua conta.</p>";
    $texto_mensagem .= "</div>";
    $texto_mensagem .= "</body></html>";

    $envio = mail(base64_decode($usuEmail), "Blue Contract - Ative sua conta", $texto_mensagem, $headers, "-f$email_remetente");

    // Exibe uma mensagem de resultado
    if ($envio) { } else { header("Location: ".URL."criar-conta?tk=".$usuToken."&eee#ve"); exit(); }

ATTEMPT 2

    //envia e-mail de confirmação
        $email_remetente = "[email protected]";
        $headers = "MIME-Version: 1.1\n";
        $headers .= "Content-type: text/HTML; charset=utf-8\n";
        $headers .= "From: $email_remetente\n"; // remetente
        $headers .= "Return-Path: $email_remetente\n"; // return-path
        $headers .= "Reply-To: $email_usuario\n"; // Endereço (devidamente validado) que o seu usuário informou no contato

        $texto_mensagem = "<html>
                            <head>
                               <title>Blue Contract - Ative sua conta</title>
                            </head>

                            <body>
                            <div style=\'margin: 40px auto; margin-left: auto; margin-right: auto; text-align: center;\'>
                                <img src=\'http://bluecontract.com.br/templates-email/cabecalho.jpg\' width=\'100%\'/>
                            </div>
                            E-mail: <b>[email protected]</b>
                            </body></html>";

         $envio = mail(base64_decode($usuEmail), "Blue Contract - Ative sua conta", $texto_mensagem, $headers, "-f$email_remetente");

         // Exibe uma mensagem de resultado
         if ($envio) { } else { header("Location: ".URL."criar-conta?tk=".$usuToken."&eee#ve"); exit(); }

I tried to do these two ways, both with the same image problem.

Remembering that the sending of email happens, then my problem is not that emails do not reach destination.

  • I like to use the swiftmailer. I find it simpler.

  • I’ve heard of swiftmailer, but I’ve never had a contact with the code or even used it, I’ve analyzed the site now and it really seems to be very simple. Interesting tool also.

2 answers

6

I think the question has a simple syntax error, because your HTML must be sending a lot of backslashes improperly. Probably this will solve:

$texto_mensagem = '
   <html>
      <head>
         <title>Blue Contract - Ative sua conta</title>
      </head>
      <body>
      <div style="margin: 40px auto; margin-left: auto; margin-right: auto; text-align: center;">
         <img src="http://bluecontract.com.br/templates-email/cabecalho.jpg" width="100%" />
      </div>
      E-mail: <b>[email protected]</b>
      </body>';

Or better yet, using HEREDOC:

$texto_mensagem = <<<FINAL
   <html>
      <head>
         <title>Blue Contract - Ative sua conta</title>
      </head>
      <body>
      <div style="margin: 40px auto; margin-left: auto;
         margin-right: auto; text-align: center;">
         <img src="http://bluecontract.com.br/templates-email/cabecalho.jpg" width="100%" />
      </div>
      E-mail: <b>[email protected]</b>
      </body>
 FINAL;

Additionally, your headers should be separated by CR LF, ( r n ), i.e. chr( 13 ) . chr( 10 ):

$crlf = chr(13).chr(10) //coloquei em variável apenas para facilitar testes
$headers = "MIME-Version: 1.1".$crlf;
$headers .= "Content-type: text/HTML; charset=utf-8".$crlf;
$headers .= "From: $email_remetente".$crlf; // remetente
$headers .= "Return-Path: $email_remetente".$crlf; // return-path
$headers .= "Reply-To: $email_usuario".$crlf; // 

And to help the debug, should replace the base64_decode by a literal address for testing.


As for the authenticity of emails

One of the things that can help, is to examine the headers of the original received by the party, to analyze the reasons for the lock. A likely improvement would be to add SPF records to the domain’s DNS server, authorizing the machine that sends emails as reliable.

Example: allowing sending of any IP between 192.168.0.1 and 192.168.255.255:

"v=spf1 ip4:192.168.0.1/16 -all"

Just add a TXT entry with the above data, for example. Do not forget to include all possible valid email sources in the domain in the rules. The subject deserves further study.


See more about SPF on Antispam Br.

  • I forgot to mention, the backslashes in this case I used in the attempt to escape the single/double quotes, I tried also without backslash, in fact were the first attempts and did not succeed. I tried with the code you passed and I didn’t succeed either.

4


I was able to solve my problem through PHP Mailer. First of all you should download PHP Mailer and unzip it inside your project folder, then don’t forget to include it in your file. php

<?php
require_once("phpmailer/class.phpmailer.php"); // requer a class do PHPMAILER

//envia e-mail de confirmação
$usuEmail = "[email protected]"; // email para onde será enviado (destinatário)
$usuNome = "João da Silva"; // nome para quem será enviado (destinatário)

$mail = new PHPMailer();
$mail->isSMTP();  // send via SMTP
$mail->Host = 'mail.seusite.com.br'; //Endereço do seu Servidor de Email
$mail->SMTPAuth = true; // true se o email é autenticado
$mail->Port = '587'; // Porta para autenticação smtp geralmente é a 587;
$mail->Username = '[email protected]'; // Seu endereço de email que envia os email
$mail->Password = "SUA_SENHA"; // senha do usuário que envia o email

$mail->From = '[email protected]'; //a pessoa que ta enviando o email

$mail->FromName = 'NOME DO REMETENTE (ASSUNTO)'; //Nome de quem ta enviando...
$mail->AddAddress($usuEmail, $usuNome); //e-mail, nome
$mail->AddReplyTo("[email protected]", "NOME DO MEU SITE/EMAIL"); //e-mail para respostas e nome do site ou email que receberá respostas

$mail->WordWrap = 50; // Quebra de linha
$mail->IsHTML(true); // Se for true é enviando email no formato HTML
$mail->Subject = "ASSUNTO DO EMAIL"; //Assunto do seu Email
$mail->Body = utf8_decode("
<meta charset='utf-8'/>
<body>
<div style='min-height: 250px;'>
    <div style='font: 14px Arial, Tahoma; padding: 0 0 30px 0; text-align: center; margin: 0 auto; border: 1px solid #d9d9d9; border-radius: 5px;'>
        <img src='cid:cabecalho' width='100%'/>
        <h1>Ative sua conta</h1>
        <p>Através de nosso website, você efetuou um cadastro.</p>
        <p>Agora, para finalizar seu cadastro é necessário confirmar sua conta.</p>
        <br><a href='#' style='background: #006699; padding: 10px 20px 10px 20px; margin: 10px auto; color: #fff; text-decoration: none; font-weight: bold;'>Ative sua conta</a>
        <br>
        <p>Caso não esteja conseguindo utilizar este botão, copie e cole o link abaixo em seu navegador:</p><pre>meusite.com.br/ativar-conta </pre>

        <img src='cid:rodape' width='100%'/>

    </div>
</div>
</body>

"); //Conteudo HTML
$mail->AltBody = "Para mensagens somente texto"; //Somente Texto

//adiciona arquivos em anexo
$mail->AddEmbeddedImage('pasta_da_imagem/cabecalho.jpg', 'cabecalho');
$mail->AddEmbeddedImage('pasta_da_imagem/rodape.jpg', 'rodape');

$envio = $mail->Send(); //envia o e-mail

// Limpa os destinatários e os anexos
$mail->ClearAllRecipients();
$mail->ClearAttachments();

// Exibe uma mensagem de resultado
if ($envio) { echo "enviado"; } else { echo "O e-mail não pode ser enviado, ocorreu um erro"; }

//
?>

The functional code is above, below you will find only the explanation of how to customize it and function.

How the files are attached in the email?

It is a very simple solution, if you analyze well you will see that all the files attachment can be done with only one line of code:

//adiciona arquivos em anexo
$mail->AddEmbeddedImage('pasta_da_imagem/cabecalho.jpg', 'cabecalho');
$mail->AddEmbeddedImage('pasta_da_imagem/rodape.jpg', 'rodape');

If you want to add more attachments just repeat the line by changing the file name and its name. Ex.: $mail->AddEmbeddedImage('pasta_da_imagem/meuarquivo.jpg', 'nome_do_arquivo');


How to use the attachment in HTML?

All you need to do is use cid:nome_do_arquivo, remembering that after the two points : you will put the name you called your file when attaching it in the email.

I don’t want to leave the password exposed

If you want to avoid leaving the password exposed in the file, use some encodings that are not one-way, even simple can make it a little difficult for laymen and the password is not easily shown. A good example is base64_encode() You can use something like:

$mail->Password = base64_decode("SUA_SENHA_CRIPTOGRAFADA_COM_BASE64_ENCODE");
  • Tiago, and what is the solution for email not to go in the spam folder ? Not clear in your reply.

  • In this case the emails are already authenticated, not to go to the SPAM folder as occurs in some emails the solution I found was not to use attached images, because this can be considered SPAM. Another case is that if in the variable $mail->From you put an email address other than that on your site, or even put one that does not exist on your hosting may cause you to fall into SPAM.

  • It is also worth mentioning that in the @Bacco response just above http://answall.com/a/36912/6392 he quoted something like registros SPF no servidor de DNS do domínio, I didn’t understand very well about how it works, I did a research but it is worth trying to learn more, maybe solve the problems.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.