Administración > Base de Conocimientos - FAQs > Depto. Tecnico > Correo electrónico > Que es y como se utiliza PHPMAILER


Que es y como se utiliza PHPMAILER




Pagina nueva 2

Uso de la clase PHPMailer

1 . Introduccion
2 . ¿Que es phpmailer?
3 . ¿Por que usar phpmailer?
4 . Pasos a seguir para usar phpmailer
5 . Ejemplo sencillo
6 . Ejemplo algo mas complicado
7 . Conclusiones y enlaces

Introduccion

El objeto de este escrito es presentar al lector la clase PHPMailer con la que podra realizar todas aquellas cosas que nunca ha podido realizar con la funcion mail() de PHP.

En primer lugar se tratara de explicar que es y las ventajas que ofrece PHPMailer, a continuacion se describiran las propiedades y metodos principales de esta clase. Para aclarar las posibles dudas se expondran dos ejemplos en los que se vera como enviar correo a traves de una cuenta gratuita creada en hotpop.

¿Que es phpmailer?

PHPMailer es una clase php para enviar emails basada en el componente active server ASPMail. Permite de una forma sencilla tareas complejas como por ejemplo:

  • Enviar mensajes de correo con ficheros adjuntos (attachments)
  • enviar mensajes de correo en formato HTML

Con PHPMailer se pueden enviar emails via sendmail, PHP mail(), o con SMTP. Lo mas recomendable es usando smtp por dos razones:

  • Con phpmailer se pueden usar varios servidores SMTP. Esto permite repartir la carga entre varias computadoras, con lo que se podran enviar un mayor numero de mensajes en un tiempo menor.
  • Ademas los servidores SMTP permiten mensajes con multimples to's (destinatarios), cc's (Las direcciones que aparezcan en este campo recibiran el mensaje. Todos los destinatarios veran las direcciones que aparecen en la seccion Cc), bcc's (Las direcciones que aparezcan en el campo Bcc recibiran el mensaje. Sin embargo, ninguno de los destinatarios podra ver las direcciones que fueron incluidas en la seccion Bcc) y Reply-tos (direcciones de respuesta)

¿Por que usar phpmailer?

Es posible enviar email con la funcion mail() de php, pero dicha funcion no permite algunas de las mas populares caracteristicas que proporcionan los clientes de correo usados actualmente. Entre estas caracteristicas se encuentran el envio de email con ficheros adjuntos.

PHPMailer hace facil esta dificil tarea de enviar correos con estas caracteristicas y puedes incluso utilizar tu propio servidor smtp aunque este requiera autenticacion (un nombre de usuario y contraseña), con lo que se podra usar una cuenta gratuita de correo obtenida por ejemplo en hotpop.

Pasos a seguir para usar phpmailer

  • Necesitamos el fichero class.phpmailer.php que es la clase PHPMailer propiamente dicha y tambien el fichero class.smtp.php que nos permite el envio de emails a traves de un servidor smtp.
  • El siguiente trozo de codigo es necesario para instanciar desde nuestra pagina php a la clase PHPMAiler. En la primera linea incluimos el fichero class.phpmailer.php y en la segunda creamos un objeto de la clase PHPMailer:
          require("class.phpmailer.php");       $mail = new PHPMailer();  
  • Una vez instanciado el objeto de la clase PHPMailer es necesario configuar sus propiedades y llamar a sus metodos. A continuacion enumero propiedades y metodos principales de la clase PHPMailer.
  • Propiedades:

    NombreDescripcionValor por defecto
    AltBody Establece el cuerpo del mensaje como solo de texto ""
    Body Establece el cuerpo del mensaje.Puede ser texto simple o con formato HTMl. Si es con formato HTMl hay que ejecutar el metodo IsHTML(True) ""
    ConfirmReadingTo Establece la direccion de correo a la que se enviara una Confirmacion de que el correo ha sido leido ""
    ErrorInfo Informa del error mas reciente producido al intentar enviar un email ""
    From Establece la direccion de correo de origen del Mensaje root@localhost
    FromName Establece el nombre de quien envia el mensaje Root User
    Host Establece el servidor SMTP. Pueden ser varios separados por ; Localhost
    Mailer Establece el metodo para enviar el mensaje puede ser mail, senmail o smtp. Se recomienda usar smtp siempre que sea posible Mail
    Password Establece la contraseña del servidor SMTP ""
    PluginDir Establece el directorio donde estan incluidos los plugins de phpmailer. Muy util para indicar el directorio en el que se encuentra la clase SMTP ""
    Port Establece el puerto por defecto del servidor SMTP 25
    ReplyTo Establece todas las direcciones Reply-To Array()
    SMTPAuth Establece la autentificacion SMTP False
    Subject Establece el asunto del mensaje ""
    Timeout Establece el timeout del servidor STMP en segundos 10
    Username Establece el nombre de usuario SMTP ""
    WordWrap Establece el word Wrapping del cuerpo de un mensaje a un numero determinado de caracteres 0

    Metodos:

    NombreSintaxisDescripcion
    AddAddress void AddAddress ( $address, $name ) Añade una direccion de destino del mensaje. El parametro $name es opcional
    AddAttachment bool AddAttachment ( $path, $name, [$encoding = "base64"], [$type = "application/octet-stream"] ) Añade un fichero adjunto al mensaje.
    Retorna false si el fichero no pudo ser encontrado.
    $path, es la ruta del archivo puede ser relativa al script php (no a la clase PHPMailer) o una ruta absoluta. Se aconseja usar rutas relativas
    $name, nombre del fichero
    $encoding, tipo de codificacion. Se aconseja dejar la predeterminada
    $type, el valor por defecto funciona con cualquier clase de archivo. Se puede usar un tipo especifico como por ejemplo image/jpeg
    AddBBC void AddBCC ( $address, $name ) Añade una direccion BCC.
    AddCC void AddCC ( $address, $name ) Añade una direccion CC
    AddReplyTo void AddReplyTo ( $address, $name ) Añade una direccion Reply-To
    ClearAddresses void ClearAddresses () Borra todas las direcciones de destino establecidas anteriormente
    ClearAttachments void ClearAttachments () Borra todos los ficheros adjuntos establecidos anteriormente
    IsHTML void IsHTML ( $bool ) Establece el tipo de mensaje a HTML
    Send bool Send ( ) Envia el mensaje, devuelve false si ha habido algun problema. Consultando la propiedad ErrorInfo se puede saber cual ha sido el problema

Ejemplo sencillo

Esta primera aplicacion de ejemplo aplicacion1.zip va a estar formada por:

  • Una pagina principal llamada ejemplo.php
  • Un subdirectorio llamado includes donde estaran los ficheros class.phpmailer.php y class.smtp.php

El objetivo de la aplicacion es mandar un mensaje de prueba mediante una cuenta de correo gratuita de hotpop. Asi pues, el primer paso sera crear una cuenta en hotpop, como nombre de usuario y password para dicha cuenta pondre por ejemplo micuenta y mipassword respectivamente, al acabar de crear la cuenta nos dara la bienvenida y nos dira que el servidor SMTP es smtp.hotpop.com. Por tanto, para enviar emails mediante phpmailer tendremos una cuenta gratuita en http://www.hotpop.com con estas caracteristicas:

  • SMTP Server: smtp.hotpop.com
  • Usuario: micuenta@HotPOP.com
  • Clave: mipassword

La direccion de destino a la que enviare el mensaje sera por ejemplo direccion@destino.com

Codigo de ejemplo.php:
// primero hay que incluir la clase phpmailer para poder instanciar
//un objeto de la misma
require "includes/class.phpmailer.php";

//instanciamos un objeto de la clase phpmailer al que llamamos
//por ejemplo mail
$mail = new phpmailer();

//Definimos las propiedades y llamamos a los metodos
//correspondientes del objeto mail

//Con PluginDir le indicamos a la clase phpmailer donde se
//encuentra la clase smtp que como he comentado al principio de
//este ejemplo va a estar en el subdirectorio includes
$mail->PluginDir = "includes/";

//Con la propiedad Mailer le indicamos que vamos a usar un
//servidor smtp
$mail->Mailer = "smtp";

//Asignamos a Host el nombre de nuestro servidor smtp
$mail->Host = "smtp.hotpop.com";

//Le indicamos que el servidor smtp requiere autenticacion
$mail->SMTPAuth = true;

//Le decimos cual es nuestro nombre de usuario y password
$mail->Username = "micuenta@HotPOP.com";
$mail->Password = "mipassword";

//Indicamos cual es nuestra direccion de correo y el nombre que
//queremos que vea el usuario que lee nuestro correo
$mail->From = "micuenta@HotPOP.com";
$mail->FromName = "Eduardo Garcia";

//el valor por defecto 10 de Timeout es un poco escaso dado que voy a usar
//una cuenta gratuita, por tanto lo pongo a 30
$mail->Timeout=30;

//Indicamos cual es la direccion de destino del correo
$mail->AddAddress("direccion@destino.com");

//Asignamos asunto y cuerpo del mensaje
//El cuerpo del mensaje lo ponemos en formato html, haciendo
//que se vea en negrita
$mail->Subject = "Prueba de phpmailer";
$mail->Body = "Mensaje de prueba mandado con phpmailer en formato html";

//Definimos AltBody por si el destinatario del correo no admite email con formato html
$mail->AltBody = "Mensaje de prueba mandado con phpmailer en formato solo texto";

//se envia el mensaje, si no ha habido problemas
//la variable $exito tendra el valor true
$exito = $mail->Send();

//Si el mensaje no ha podido ser enviado se realizaran 4 intentos mas como mucho
//para intentar enviar el mensaje, cada intento se hara 5 segundos despues
//del anterior, para ello se usa la funcion sleep
$intentos=1;
while ((!$exito) && ($intentos < 5)) {
sleep(5);
//echo $mail->ErrorInfo;
$exito = $mail->Send();
$intentos=$intentos+1;

}


if(!$exito)
{
echo "Problemas enviando correo electronico a ".$valor;
echo "
".$mail->ErrorInfo;
}
else
{
echo "Mensaje enviado correctamente";
}
?>

Comentarios al ejemplo
Tres cosas a destacar:

Al usar un servidor smtp para el envio del mensaje es muy importante definir la propiedad PluginDir que indica donde se encuentra el fichero class.smtp.php que contiene la clase SMTP, en este caso se encuentra en el subdirectorio includes

El uso simultaneo de las propiedades Body y AltBody. Se debe hacer cuando queremos mandar un mensaje con formato Html ya que es posible que el destinatario acepte solo correos en formato texto. Al definir las dos propiedades, Body y AltBody, no es necesario ejecutar el metodo IsHTML(True) cuando a Body se le asigna un mensaje en formato Html

La tercera y mas importante a tener en cuenta es el hecho de que el exito en el envio del mail no depende solo de la clase PHPMailer sino que es vital el tiempo que el servidor smtp necesita para autenticar al usuario asi como el tiempo que tarda dicho servidor en enviar un correo.

Por tanto es fundamental proporcionarle al servidor el tiempo que le hace falta, ello se cosigue de dos formas: Por un lado aumentando el valor de la propiedad Timeout pasando por ejemplo de 10 a 30 segundos; Y por otro lado reintentando el envio del mensaje un numero razonable de veces (por ejemplo 5), dejando un tiempo de espera (por ejemplo 5 segundos), entre cada intento.

Mediante la combinacion de estos 3 factores: Propiedad Tiemout, numero de intentos para enviar el mensaje y tiempo de espera entre cada intento evitaremos los dos mensajes de error mas frecuentes que nos puede dar la clase PHPMailer, relacionados con el tiempo que necesita el servidor smtp para realizar su funcion, y que son:

  • SMTP Error: The following recipientes failed ......
  • SMTP Error: Could not authenticate

Ejemplo algo mas complicado

El objetivo de esta segunda aplicacion de ejemplo aplicacion2.zip va a ser enviar un correo con un fichero adjunto a 2 direcciones de destino diferentes (al menos debe haber una direccion de destino, el envio de un fichero adjunto sera opcional. Por simplificar no compruebo que la sintaxis de las direcciones de correo introducidas en los campos de texto sea correcta).

Esta aplicacion va a estar formada por:

  • Una pagina principal llamada ejemplo2.php
  • Un subdirectorio llamado includes donde estaran los ficheros class.phpmailer.php y class.smtp.php

En la pagina principal ejemplo2.php vamos a tener un formulario como el que se ve a continuacion

Direccion de destino1:
Direccion de destino2:
Fichero adjunto:

Para poder enviar el fichero adjunto vamos a emplear en el formulario una etiqueta INPUT de tipo FILE que es soportada por Netscape Navigator 2.0 en adelante e Internet Explorer 4.0 en adelante. Para que funcione es necesario:

  • Que el formulario use el metodo post
  • Que el atributo enctype tenga el valor multipart/form-data
  • Ademas al formulario hay que a�adirle un campo oculto de nombre MAX_FILE_SIZE, al cual le daremos el valor en bytes del tama�o maximo del archivo a descargar. Dado que voy a emplear la cuenta gratuita de hotpop empleada en el ejemplo anterior y dicha cuenta no permite enviar mensajes de mas de 500kb voy a limitar a 300kb (307200 bytes) el tama�o maximo del archivo.

Codigo de ejemplo2.php:

Codigo de ejemplo2.php:
//Es necesario que al menos halla una direccion de destino
$error="";

if ($enviar) {
if ((!$email1) && (!$email2)) {
$error.="Debe indicar al menos una direccion de destino";
}
}

if ($enviar && !$error) {

//creamos un array que estara formado por las direcciones de destino
if ($email1) {
$direcciones["direccion1"]=$email1;
}
if ($email2) {
$direcciones["direccion2"]=$email2;
}


//pasamos a enviar el correo

// primero hay que incluir la clase phpmailer para poder instanciar
//un objeto de la misma
require "includes/class.phpmailer.php";

//instanciamos un objeto de la clase phpmailer al que llamamos
//por ejemplo mail
$mail = new phpmailer();

//Definimos las propiedades y llamamos a los metodos
//correspondientes del objeto mail

//Con PluginDir le indicamos a la clase phpmailer donde se
//encuentra la clase smtp que como he comentado al principio de
//este ejemplo va a estar en el subdirectorio includes
$mail->PluginDir = "includes/";

//Con la propiedad Mailer le indicamos que vamos a usar un
//servidor smtp
$mail->Mailer = "smtp";

//Asignamos a Host el nombre de nuestro servidor smtp
$mail->Host = "smtp.hotpop.com";

//Le indicamos que el servidor smtp requiere autenticacion
$mail->SMTPAuth = true;

//Le decimos cual es nuestro nombre de usuario y password
$mail->Username = "micuentaf@HotPOP.com";
$mail->Password = "mipassword";

//Indicamos cual es nuestra direccion de correo y el nombre que
//queremos que vea el usuario que lee nuestro correo
$mail->From = "micuenta@HotPOP.com";

$mail->FromName = "Eduardo Garcia";

//Asignamos asunto y cuerpo del mensaje
//El cuerpo del mensaje lo ponemos en formato html, haciendo
//que se vea en negrita
$mail->Subject = "Prueba de phpmailer";
$mail->Body = "Mensaje de prueba mandado con phpmailer en formato html";

//Definimos AltBody por si el destinatario del correo no admite
//email con formato html
$mail->AltBody ="Mensaje de prueba mandado con phpmailer en formato texto";

//el valor por defecto 10 de Timeout es un poco escaso dado que voy a usar
//una cuenta gratuita y voy a usar attachments, por tanto lo pongo a 120
$mail->Timeout=120;

//Indicamos el fichero a adjuntar si el usuario selecciono uno en el formulario
if ($achivo !="none") {
$mail->AddAttachment($archivo,$archivo_name);
}

//Indicamos cuales son las direcciones de destino del correo y enviamos
//los mensajes
reset($direcciones);
while (list($clave, $valor)=each($direcciones)) {
$mail->AddAddress($valor);

//se envia el mensaje, si no ha habido problemas la variable $success
//tendra el valor true
$exito = $mail->Send();

//Si el mensaje no ha podido ser enviado se realizaran 4 intentos mas
//como mucho para intentar enviar el mensaje, cada intento se hara 5 s
//segundos despues del anterior, para ello se usa la funcion sleep
$intentos=1;
while((!$exito)&&($intentos<5)&&($mail->ErrorInfo!="SMTP Error: Data not accepted")){
sleep(5);
//echo $mail->ErrorInfo;
$exito = $mail->Send();
$intentos=$intentos+1;
}

//La clase phpmailer tiene un pequeño bug y es que cuando envia un mail con
//attachment la variable ErrorInfo adquiere el valor Data not accepted, dicho
//valor no debe confundirnos ya que el mensaje ha sido enviado correctamente
if ($mail->ErrorInfo=="SMTP Error: Data not accepted") {
$exito=true;
}

if(!$exito)
{
echo "Problemas enviando correo electronico a ".$valor;
echo "
".$mail->ErrorInfo;
}
else
{
//Mostramos un mensaje indicando las direccion de
//destino y fichero adjunto enviado en el mensaje
$mensaje="

Has enviado un mensaje a:
";
$mensaje.=$valor." ";
if ($archivo !="none") {
$mensaje.="Con un fichero adjunto llamado ".$archivo_name;
}
$mensaje.="

";
echo $mensaje;


}
// Borro las direcciones de destino establecidas anteriormente
$mail->ClearAddresses();

}
echo " VOLVER AL FORMULARIO";
}
else {
?>



$error";?>




















Direccion de destino1:
Direccion de destino2:
Fichero adjunto:




}
?>

Comentarios al ejemplo 2
En el caso de que halla dos direcciones de destino, en lugar de añadir las dos direcciones a la vez mediante llamadas consecutivas al metodo AddAddresses lo que hago es enviar uno a uno cada correo:
  • Introduzco las direcciones de destino en un array llamado direccines
  • Añado la primera direccion incluida en ese array con el metodo AddAddresses
  • Intento enviar el mensaje, muestro en pantalla si el mensaje ha podido ser enviado correctamente o no
  • borro la direccion anteriormente añadida con el metodo ClearAddresses
  • Añado la siguiente direccion incluida en el array direcciones con el metodo AddAddresses
  • Intento enviar el mensaje, muestro en pantalla si el mensaje ha podido ser enviado correctamente o no

La ventaja de hacerlo uno a uno y no los dos a la vez es que tengo un mayor control sobre los posibles errores que puedan suceder, identificando en cada momento a que direccion se le ha podido enviar el mail y a cual no

Aumento el Timeout a 120 ya que enviar un fichero adjunto requiere mas tiempo que enviar un mensaje corto

Quiza lo que llame mas la atencion es el trato que he dado al error SMTP Error: Data not accepted. Dicho error aparece siempre que enviamos un fichero adjunto pero no debe incomodarnos ya que el mensaje llega perfectamente, se trata de un bug de la clase PHPMailer y como tal hay que tratarlo, es decir, si aparece ese error no lo tendremos en cuenta.

Conclusiones y enlaces

Como se ha podido observar en los dos ejemplos anteriores con PHPMailer es posible el envio de un email tan complejo o tan simple como se quiera. Hemos visto los 3 errores mas frecuentes que se pueden dar al usar la clase phpmailer:

  • SMTP Error: The following recipientes failed ......
  • SMTP Error: Could not authenticate
  • SMTP Error: Data not accepted

La solucion a los 2 primeros es la que ya apunte en Comentarios al ejemplo, y se trata de buscar la mejor combinacion de los factores Timeout, numero de intentos para enviar el mensaje e intervalo de tiempo entre cada intento. Los valores que he utilizado son orientativos no deben tomarse al pie de la letra ya que para realizar los ejemplos me parecia adecuado usar una cuenta gratuita obtenida en la Web, pero el lector seguramente usara una cuenta que le halla proporcionado su proveedor de Internet y dicha cuenta puede requerir unos valores para esos factores que coincidan o no con los que yo he propuesto, tambien dependera del uso que quiera dar a la cuenta, no es lo mismo si la va a usar para enviar correos con formato solo texto a pocos destinatarios que si quiere enviar correos con ficheros adjuntos a muchos destinatarios.

La solucion al tercero es la ya apuntada en Comentarios al ejemplo 2, es decir, ignorar dicho error porque el mensaje llega correctamente.

He comentado los aspectos mas importantes de la clase PHPMailer, para una mayor informacion sugiero consultar la web de los creadores de esta estupenda clase.

Puede Descargar un demo de formulario y processo desde: http://www.atlanticadigital.net/index.php/Descargas-Utiles/Manuales-de-Configuraciones-y-Clientes-de-Correo/



¿Fue útil la respuesta?

Agregar a Favoritos Agregar a Favoritos    Imprimir éste Artículo Imprimir éste Artículo

Leer también