+7

Enviando anexos com a função mail()

criado por Vinicius G Mommensohn em 11/12/2003 9:14am
Bom, como todo mundo gosta, vamos direto ao assunto! Como fazer para enviar anexos com o email pelo PHP???

Para utilizar desse script é necessário que a função mail() de seu PHP esteja funcionando! Lembrando que, para ela funcionar, você deve ter instalado algum server de email (qmail, sendmail) anteriormente já que o php, na hora de compilar, procura pelo link simbolico do sendmail no sistema.

Na hora de desenvolver o script, tomei como referencia os emails anexados pelo Outlook Express 6 (que é um dos mais utilizados atualmente :/ ).

Vamos dizer que você queira anexar o arquivo imagem.gif em seu e-mail. Vou colocar o código primeiro e depois a explicação.

<?php
$boundary = strtotime('NOW');
   
$headers = "From: Eu <meu@email.com.br>\n";
$headers .= "MIME-Version: 1.0\n";
$headers .= "Content-Type: multipart/mixed; boundary=\"" . $boundary . "\"\n";
 
$msg = "--" . $boundary . "\n";
$msg .= "Content-Type: text/plain; charset=\"iso-8859-1\"\n";
$msg .= "Content-Transfer-Encoding: quoted-printable\n\n"; 

$msg .= "Aqui eu escrevo o texto do email\n";
 
$msg .= "--" . $boundary . "\n";
$msg .= "Content-Transfer-Encoding: base64\n";
$msg .= "Content-Disposition: attachment; filename=\"imagem.gif\"\n\n";

ob_start();
   readfile("imagem.gif");
   $enc = ob_get_contents();
ob_end_clean();

$msg_temp = base64_encode($enc). "\n";
$tmp[1] = strlen($msg_temp);
$tmp[2] = ceil($tmp[1]/76);

for ($b = 0; $b <= $tmp[2]; $b++) {
    $tmp[3] = $b * 76;
    $msg .= substr($msg_temp, $tmp[3], 76) . "\n";
}

unset($msg_temp, $tmp, $enc);

mail("para@email.com.br", "Assunto", $msg, $headers);

?>

Bom, agora vamos as explicações!

---------
$boundary = strtotime('NOW');

$headers = "From: Eu <meu@email.com.br>\n";
$headers .= "MIME-Version: 1.0\n";
$headers .= "Content-Type: multipart/mixed; boundary=\"" . $boundary . "\"\n";
---------

Boundary é a marcação que o programa de email vai levar em conta na hora da separação das partes do email. No corpo do email ele é identificado como '--' mais o boundary!

Em baixo defini alguns cabeçalhos do email. Isso fica a gosto de cada um.

---------
$msg = "--" . $boundary . "\n";
$msg .= "Content-Type: text/plain; charset=\"iso-8859-1\"\n";
$msg .= "Content-Transfer-Encoding: quoted-printable\n\n";

$msg .= "Aqui eu escrevo o texto do email\n";
---------

Essa parte é a parte do email que fica o texto! Neste caso ele está em texto puro (text/plain). Mas dá para ser em html (text/html) e dae só precisa colocar as tags do html!

---------
$msg .= "--" . $boundary . "\n";
$msg .= "Content-Transfer-Encoding: base64\n";
$msg .= "Content-Disposition: attachment; filename=\"imagem.gif\"\n\n";

ob_start();
readfile("imagem.gif");
$enc = ob_get_contents();
ob_end_clean();

$msg_temp = base64_encode($enc). "\n";
$tmp[1] = strlen($msg_temp);
$tmp[2] = ceil($tmp[1]/76);

for ($b = 0; $b <= $tmp[2]; $b++) {
$tmp[3] = $b * 76;
$msg .= substr($msg_temp, $tmp[3], 76) . "\n";
}

unset($msg_temp, $tmp, $enc);
---------

Esta parte define a imagem em si! Primeiramente eu envio os identificadores de anexo, com o nome do anexo. Mais embaixo, eu pego o conteúdo do arquivo ( readfile("imagem.gif"); ) e o encripto com o base64 (formato padrão dos anexos no email!).

É nessa parte que tem que se tomar cuidado, pois pelo RFC as linhas do email não podem ser muito grandes. Por isso o FOR "quebra" o conteudo do arquivo em pedaços de 76 caracteres!

Lembrando que, para mandar mais de um arquivo, é colocar um for para pegar os arquivos que você quer... o for fica por conta de voces!!

Libero da memória as variáveis que não me interessam e finalmente...

---------
mail("para@email.com.br", "Assunto", $msg, $headers);
---------

Envia-se o email!!!

E é isso!!!! Com esse código e sua imaginação você consegue fazer muitas coisas com o email!!! :) Lembrando que isso é só o conceito básico, a partir desse código você pode desenvolver sua imaginação (criar funçoes, classes, etc)...



Vinicius Mommensohn

Comentários:

Mostrando 1 - 10 de 28 comentários
Bom dia, meu amigo eu fiz igualzinho tá no seu código, usei um aruqivo que publico dinamicamente, figura jpg

porém o que recebi no e-mail vou uma pancada de códigos e letras.

o que está errado ?
05/12/2008 6:41pm (~16 anos atrás)

Marcio Silva disse:
Parabéns pelo artigo Vinicius!

eu tenho uma dúvida...por exemplo, eu desenvolvi um sistema que gera boleto bancário(uma página .php no formato do boleto com imagens)...eu gostaria de poder enviar esse boleto por e-mail. vc teria alguma sugestão?

obrigado!
12/02/2008 1:34pm (~17 anos atrás)

Copiei o script do jeito que estava... e se eu troco pra text/html e coloco html la na mensagem o email chega todo codificado estranho e sem anexo...

alguem teve esse erro? sabe como resolver?

pode dar um exemplo usando o email em html?

valeu
02/03/2007 2:15pm (~18 anos atrás)

Estou tendo problemas com isto:
SMTP server response: 503 5.0.0 Need RCPT (recipient)

Quem puder me ajudar, agradeço!
08/02/2006 5:30am (~19 anos atrás)

Sensacional o script!Parabéns! Mas não esquecer que para funcionar precisa declarar na TAG <FORM> a seguinte configuração enctype="multipart/form-data" ficando mais ou menos assim
<FORM enctype="multipart/form-data" method="post" action="x.php">
09/09/2005 1:21pm (~19 anos atrás)

Troque o \n do script por \r\n. Ai ele vai funcionar!!
27/07/2005 6:52pm (~19 anos atrás)

Warning: mail(): SMTP server response: 451 See http://pobox.com/~djb/docs/smtplf.html
26/07/2005 3:31pm (~19 anos atrás)

Ae esse script é DUKA mano, meus parabéns.

Mas estou envontrando uns problemas pra enviar as mensagens como HTML.

Quando coloco as tags o arquivo vai tranquilo, porém o corpo da mensagem não vem com o código exato que eu coloquei, por exemplo, você coloca uma imagem e dá problema vc coloca os códigos e parece que detona tudo, o texto vem mas não formatado do jeito que eu quero.

Não sei se ficou claro minha explicação mas esse é o problema.
20/07/2005 3:50pm (~19 anos atrás)

Joni disse:
Seguinte alterei as seguintes linhas pra receber um arquivo do tipo .doc:

$msg .= "Content-Disposition: attachment; filename=\"arquivo.doc\"\n\n";

readfile("arquivo.doc");

eu recebo o arquivo .doc e qdo tento abrir da a seguinte mensagem:
Warning: readfile(curriculo.doc): failed to open stream: No such file or directory in /home/changes/www/textos/mail.php on line 31<br />"

o que ha de errado???
24/06/2005 3:01pm (~19 anos atrás)

Vinicius,

Seu script está muito bom, mas tenho um comentário a fazer:

É interessante, quando se anexa o arquivo, dizer qual o tipo que ele é. Assim webmails, por exemplo, não ficam perdidos para saber o que é o arquivo.

Para isso, entre as linhas de Content-Transfer e Content-Disposition é bom colocar esta:

Content-Type: "image/gif"; name=\"nome_arq.gif\"\n";

Obviamente que o tipo de arquivo e o nome podem ser passados via variáveis. No caso do tipo, usar $_FILES['campoform']['type']

Abraços
11/11/2004 6:52am (~20 anos atrás)

Novo Comentário:

(Você pode usar tags como <b>, <i> ou <code>. URLs serão convertidas para links automaticamente.)