Envío de e-mails con attachments (adjuntos)
Si lo que queremos es enviar un correo electrónico con un archivo adjunto (attachment) entonces podemos usar cualquiera de estos dos códigos, uno lo encontré en el libro PHP Professional de la Editorial Wrox y el otro me lo pasó un colega en el desarrollo de PHP.
emailArchivo.php
<?
include "mime_mail.inc";
$filename = "color.gif";
$content_type = "image/gif";
# read a JPEG picture from the disk
$fd = fopen($filename, "r");
$data = fread($fd, filesize($filename));
fclose($fd);
# create object instance
$mail = new mime_mail;
# set all data slots
$mail->from = "lizo@address.com";
$mail->to = "abc@mime_mail.com";
$mail->subject = "welcome!";
$mail->body = "Here goes the real
text of the e-mail. You can write over
multiple lines, of course.";
# append the attachment
$mail->add_attachment($data, $filename, $content_type);
# send e-mail
$mail->send();
?>
// store as "mime_mail.inc"
class mime_mail
{
var $parts;
var $to;
var $from;
var $headers;
var $subject;
var $body;
/*
* void mime_mail()
* class constructor
*/
function mime_mail() {
$this->parts = array();
$this->to = "";
$this->from = "";
$this->subject = "";
$this->body = "";
$this->headers = "";
}
/*
* void add_attachment(string message, [string name], [string ctype])
* Add an attachment to the mail object
*/
function add_attachment($message, $name = "", $ctype =
"application/octet-stream") {
$this->parts[] = array (
"ctype" => $ctype,
"message" => $message,
"encode" => $encode,
"name" => $name
);
}
/*
* void build_message(array part=
* Build message parts of an multipart mail
*/
function build_message($part) {
$message = $part[ "message"];
$message = chunk_split(base64_encode($message));
$encoding = "base64";
return "Content-Type: ".$part[ "ctype"].
($part[ "name"]? "; name = \"".$part[ "name"].
"\"" : "").
"\nContent-Transfer-Encoding: $encoding\n\n$message\n";
}
/*
* void build_multipart()
* Build a multipart mail
*/
function build_multipart() {
$boundary = "b".md5(uniqid(time()));
$multipart =
"Content-Type: multipart/mixed; boundary = $boundary\n\nThis is a MIME encoded
message.\n\n--$boundary";
for($i = sizeof($this->parts)-1; $i >= 0; $i--)
{
$multipart .= "\n".$this->build_message($this->parts[$i]).
"--$boundary";
}
return $multipart.= "--\n";
}
/*
* string get_mail()
* returns the constructed mail
*/
function get_mail($complete = true) {
$mime = "";
if (!empty($this->from))
$mime .= "From: ".$this->from. "\n";
if (!empty($this->headers))
$mime .= $this->headers. "\n";
if ($complete) {
if (!empty($this->to)) {
$mime .= "To: $this->to\n";
}
if (!empty($this->subject)) {
$mime .= "Subject: $this->subject\n";
}
}
if (!empty($this->body))
$this->add_attachment($this->body, "", "text/html");
$mime .= "MIME-Version: 1.0\n".$this->build_multipart();
return $mime;
}
/*
* void send()
* Send the mail (last class-function to be called)
*/
function send() {
$mime = $this->get_mail(false);
mail($this->to, $this->subject, "", $mime);
}
}; // end of class
emailArchivo2.php
<?php
/* notes from Dan Potter:
Sure. I changed a few other things in here too though.
One is that I let
you specify what the destination filename is (i.e.,
what is shows up as in
the attachment). This is useful since in a web
submission you often can't
tell what the filename was supposed to be from the
submission itself. I
also added my own version of chunk_split because our
production version of
PHP doesn't have it. You can change that back or
whatever though =).
Finally, I added an extra "\n" before the message text
gets added into the
MIME output because otherwise the message text wasn't
showing up.
*/
/*
note: someone mentioned a command-line utility called
'mutt' that
can mail attachments.
*/
/*
If chunk_split works on your system, change the call
to my_chunk_split
to chunk_split
*/
/* Note: if you don't have base64_encode on your sytem
it will not work */
/* simple class that encapsulates mail() with addition
of mime file attachment.*/
class CMailFile {
var $subject;
var $addr_to;
var $text_body;
var $text_encoded;
var $mime_headers;
var $mime_boundary =
"--==================_846811060==_";
var $smtp_headers;
function
CMailFile($subject,$to,$from,$msg,$filename,$mimetype
= "application/octet-stream", $mime_filename = false)
{
$this->subject = $subject;
$this->addr_to = $to;
$this->smtp_headers =
$this->write_smtpheaders($from);
$this->text_body = $this->write_body($msg);
$this->text_encoded =
$this->attach_file($filename,$mimetype,$mime_filename);
$this->mime_headers =
$this->write_mimeheaders($filename, $mime_filename);
}
function
attach_file($filename,$mimetype,$mime_filename) {
$encoded = $this->encode_file($filename);
if ($mime_filename) $filename = $mime_filename;
$out = "--" . $this->mime_boundary . "\n";
$out = $out . "Content-type: " . $mimetype . ";
name=\"$filename\";\n";
$out = $out . "Content-Transfer-Encoding: base64\n";
$out = $out . "Content-disposition: attachment;
filename=\"$filename\"\n\n";
$out = $out . $encoded . "\n";
$out = $out . "--" . $this->mime_boundary . "--" .
"\n";
return $out;
// added -- to notify email client attachment is done
}
function encode_file($sourcefile) {
if (is_readable($sourcefile)) {
$fd = fopen($sourcefile, "r");
$contents = fread($fd, filesize($sourcefile));
$encoded =
my_chunk_split(base64_encode($contents));
fclose($fd);
}
return $encoded;
}
function sendfile() {
$headers = $this->smtp_headers .
$this->mime_headers;
$message = $this->text_body . $this->text_encoded;
mail($this->addr_to,$this->subject,$message,$headers);
}
function write_body($msgtext) {
$out = "--" . $this->mime_boundary . "\n";
$out = $out . "Content-Type: text/plain;
charset=\"us-ascii\"\n\n";
$out = $out . $msgtext . "\n";
return $out;
}
function write_mimeheaders($filename, $mime_filename)
{
if ($mime_filename) $filename = $mime_filename;
$out = "MIME-version: 1.0\n";
$out = $out . "Content-type: multipart/mixed; ";
$out = $out . "boundary=\"$this->mime_boundary\"\n";
$out = $out . "Content-transfer-encoding: 7BIT\n";
$out = $out . "X-attachments: $filename;\n\n";
return $out;
}
function write_smtpheaders($addr_from) {
$out = "From: $addr_from\n";
$out = $out . "Reply-To: $addr_from\n";
$out = $out . "X-Mailer: PHP3\n";
$out = $out . "X-Sender: $addr_from\n";
return $out;
}
/* Splits a string by RFC2045 semantics (76 chars per
line, end with \r\n).
This is not in all PHP versions so I define one
here manuall.*/
function my_chunk_split($str)
{
$stmp = $str;
$len = strlen($stmp);
$out = "";
while ($len > 0) {
if ($len >= 76) {
$out = $out . substr($stmp, 0, 76) . "\r\n";
$stmp = substr($stmp, 76);
$len = $len - 76;
}
else {
$out = $out . $stmp . "\r\n";
$stmp = ""; $len = 0;
}
}
return $out;
}
// end script
// usage - mimetype example "image/gif"
?>
Y para usarlo hay que usar las siguientes líneas:
<?
$enviaarch= new
CMailFile($subject,$sendto,$from,$message,$filename,$mimetype);
$enviaarch->sendfile();
//Gracias a Heriberto Rosas por hacerme llegar este script
?>