Envío de boletines a emails de una base de datos MySQL

Código en PHP para el envio de boletines a emails almacenados en una base de datos.
Ahora está muy de moda el envío de boletines para informar de las novedades en las webs. El único problema es que para hacerlo, la mayoría de webmasters tienen que depender de alguna empresa (o servidor) que les gestione la base de datos y les envíe los emails cuando lo requieran.

En este artículo explicaré paso a paso como crear la tabla (en la base de datos MySQL) necesaria para el almacenamiento de los emails y posteriormente, cómo enviar un boletín a todos ellos, con el aliciente de que no aparezcan todos los destinatarios en el campo "Para:" del mensaje.

Creación de tabla en la base de datos

Mediante su gestor de la base de datos MySQL (seguramente "phpMyAdmin") debe crear una nueva tabla en su base de datos. Aquí le facilitamos el archivo de texto para ello:

CREATE TABLE usuarios (
id bigint(7) NOT NULL auto_increment,
nick varchar(100) NOT NULL,
passowrd varchar(100) NOT NULL,
nombre varchar(255) default NULL,
email varchar(100) default NULL,
KEY id (id)
)

Y quedará así en su phpMyAdmin:


Tras esto usted ya tiene la tabla necesaria para almacenar los datos dentro de una base de datos MySQL. Podría explicar como introducir los datos en esta tabla mediante formularios de registro... pero eso ya lo dejo a gusto del webmaster.

Envío del boletín

Para enviar el boletín solo debe cambiar los datos del siguiente archivo php por los de su base de datos y tendrá listo su archivo. Para enviar el boletín solo tiene que ejecutar este archivo en su servidor (cargarlo: por ejemplo, entrar en http://usuarios.lycos.es/tunombredeusuario/prueba.php):

<?php
  $mi_conexion=mysql_connect('servidor','nombre_de_usuarior','contraseña') or die('No se puedo conectar con la base de datos!');

/*
Servidor: aquí debe poner la dirección de su servidor, en la mayoría de las compañías es 'localhost'
Nombre_de_usuario: debe pone su nombre de usuario en el servidor.
Contraseña: su contraseña.
*/

   mysql_select_db('base_de_datos',$mi_conexion);

/*
Base_de_datos: nombre de su base de datos.
*/

   $query_Tabla = "SELECT email FROM usuarios ORDER BY id ASC";
   $Tabla = mysql_query($query_Tabla, $mi_conexion) or die(mysql_error());

/*
Email: es el nombre del campo que requerimos, si ha seguido nuestras instrucciones creando nuestra misma tabla en la base de datos no debe cambiar esto.
Usuarios: es el nombre de la tabla donde está el campo 'email', si ha seguido nuestras instrucciones creando nuestra misma tabla en base de datos no debe cambiar esto.
*/

   //elaboramos cadena de emails
  $losemails="";
  while ($row_Tabla=mysql_fetch_assoc($Tabla)) {
   $losemails.=($row_Tabla['email'].", ");
   }

  $largo=strlen($losemails);
   if ($largo>2)
{
   //quitamos ultimos ", "
   $losemails=substr($losemails,0,$largo-2);
}
else
{
   echo "No hay destinatarios!";
   die();
};

// se definen los argumentos de mail( ):
$asunto='Prueba de email desde PHP';
$mensaje='<html>
<head>
   <title>Titulo de la Pagina</title>
</head>
<body>
   <p>Esta es una prueba de emails en formato HTML</p>
   Precios de nuestros productos:
   <table>
    <tr>
   <th>PRODUCTO<th>PRECIO<th>PROMOCION</th>
   </tr>
  <tr>
   <td>Refresco Grande</td><td>25,50</td><td>23,00</td>
  </tr>
  <tr>
    <td>Helado Napolitano</td><td>27,50</td><td>25,00</td>
  </tr>
  <tr>
   <td>Patatas</td><td>18,50</td><td>15,00</td>
  </tr>
  </table>
</body>
</html>';

/*
Aquí debe poner su email en formato HTML
*/

$envia='enviante';
$remite='email_remitente';

/*
Enviante: Nombre del enviante
Email_remitente: email que desea mostrar como remitente.
*/

/// Envío del email:

mail(null, $asunto, $mensaje, "MIME-Version: 1.0
Content-type: text/html; charset=iso-8859-1
From: $envia <$remite>
Bcc: $losemails" . "\r\n") or die("Error al Enviar el Email");
echo "Mensaje Enviado con Éxito!"; //

   mysql_free_result($Tabla);
   mysql_close($mi_conexion);
?>
Ya tenemos nuestro sistema de envío de boletines, no tendremos que depender de nadie.

El único problema que presenta este sistema es que al no aparecer nada en el campo "Para:" del email, algunos gestores de email lo colocan como "correo no deseado". Acepto contribuciones de otros lectores para mejorarlo.

Compartir

Comentarios

pepe

29/6/2005
La verdad que muy buen articulo, y es verdad habria que ver como no tomarlo como spam. Yo no se tanto como tu pero se me ocurre una idea...

Si en vez de enviar un mail con copia a todos los destinatarios, hacemos un bucle para que ejecute la funcion mail por cada destinatario ?
Me parece que sirve, pero la pregunta es...
¿El servidor se cargaria mucho mas enviando cientos de mails para 1 solo destinatario, que enviando 1 solo mail con copia para cientos destinatarios?
Yo creo que si pero realmente no se la respuesta.
Saludos!

Gabriel Cambronero

01/7/2005
Bueno, en realidad en relación con el último comentario les digo que justamente eso fue lo que se puso al final del artículo, al no especificarse el PARA, muchas empresas de E-MAIL, tienen filtros que pueden clasificar el correo como SPAM es por eso que no les va a llegar a la totalidad de los destinatarios, no es tanto porque exista limitante porque el bucle individual simplemente es eso.. es enviar N veces el mismo email pero a diferente destinatario.

Se me ocurre aplicar la idea del compañero que posteo de primero, lo que pasa es que si son 5000... primero estarías consumiendo recursos de tu server, incluyendo el tráfico disponible.

El artículo esta excelente, pero para tales efectos quizás sea mejor utilizar un programa foráneo Advanced Mass Sender.

simon montaño

01/7/2005
no soy un experto en PHP pero creo q deberias de modificar la estructura correspondiente a las variables $headers, con eso, creo que podrias resolver el problema del que hablas en el articulo. Yo lo voy a probar si logro modificarlo lo publicare ak. saludos y buen trabajo.

Ramfiz Rodriguez

01/7/2005
Pus en realidad presenta otro problema este articulo y no sé si llamarlo de portabilidad ( no todos lo veran bien )
*** Miren mi codigo******

$mensaje = html_entity_decode(stripslashes($HTTP_POST_VARS['mensajito']));

$fromname= "JASCA";
$fromaddress= "prometeus@jasca.org";

$cabeceras = "MIME-Version: 1.0 ";
$cabeceras .= "Content-type: text/html; charset=iso-8859-1 ";
$cabeceras .= "X-Priority: 3 ";
$cabeceras .= "X-MSMail-Priority: Normal ";
$cabeceras .= "X-Mailer: php ";
$cabeceras .= "From: "".$fromname."" <".$fromaddress."> ";


while ($contek = mysql_fetch_row($syntek)){
$garza = "Saludos ". $contek[0]." ".$mensaje;
mail($contek[1],$tema,$garza, $cabeceras);
}

y de 200 correos que tengo como el 12 o 10% no lo miran bien, yo no pongo el HTML en una VARIABLE sino que lo mando via POST y como mi servidor tiene el MAGIC_QUOTES encendido tengo que hacer el StripSlashes y luego el HTML_ENTITY para que me lo tome como HTML lo que le envio. Ahora Tengo problemas de PORTABILIDAD.

leo

02/7/2005
una alternativa al problema del campo "PARA" es completarlo con una direccion de email propia y que exista.

Por ejemplo si el sitio es www.xxx.com nos creamos una casilla q sea novedades@xxx.com y enviamos el mensaje a esa direccion con todos los demas destinatarios en forma de copia oculta (BCC)

Yo lo probe con hotmail y gmail y funciona ok, no los toma como spam. inclusive no lo filtra el anti-spam del panda.


Para hacer algo mas personalizado, se podria (como bien dice otro usuario anteriormente) hacer un bucle... pero seria bueno ya que nos tomamos ese trabajo ampliar la tabla de usuarios con nombre y apellido, entonces al enviarlo utilizariamos el campo "PARA" de la siguiente forma:
$para = 'Jose Lopez <pepe@pepe.com>';
de esa forma el remitente vera su nombre al recibir el correo.

Para ampliar estos temas recomiendo el manual de PHP en formato chm que se puede descargar en español de :
http://www.php.net/download-docs.php
permite buscar funciones desde un indice. Pongan mail() en el buscador y les tirara todos los detalles con ejemplos de aplicacion.

saludos...

Italo Neira

04/7/2005
Hace poco termine de hacer un gestor de boletines en PHP similar al descrito en el articulo. Para esto utilize la libreria PHP mailer (ver http://phpmailer.sourceforge.net) que es gratuita y ofrece una clase PHPMailer con varios metodos para enviar correos de forma mas optima. Por ejemplo el metodo AddAddress permite crear listas de destinatarios de forma transparente. Otros metodos permiten agregar headers, archivos adjuntos, etc. Recomiendo lo revisen, ya que es una buena solucion ademas para el problema descrito respecto al campo "PARA" y los software anti-spam.

Pedro

05/7/2005
Yo añadiría la llamada a la función foreach cuando consultamos la cantidad de emails de la base de datos. De tal modo que la funcion FOREACH recorra uno a uno los destinatarios y envíe el email de forma personalizada para que aparente menos ser un SPAM. Entonces quedarío conceptualmente así:

$select=Select * from tabla_destinatarios

$destinatario=mysql_fetch_array $select

foreach($destinatario){
mail($destinatario["email"],"Boletin",$cuerpo_mensaje,$cabeceras);
}


SALUDOSS!!!!

jimmy

19/8/2005
Para evitar ese problema que mencionas del famoso 'para' que esta en blanco, no es mejor crear una cadena, asi se le indica sea por medio de un array, que se le indique enviar a (osea a los del para )lo que esta en la base de datos.

No soy muy diestro en explicar la idea, pero espero me entiendan.

Raúl Avilés (Autor del artículo)

26/4/2006
Agradezco de antemano todos los comentarios que he recibido para intentar mejorar el artículo. Voy a responder a la mayoría de cuestiones preguntadas (si me da tiempo xD):

-Solución al campo 'PARA', para que no se filtre en el anti-spam: tal y como ha dicho uno de los lectores, se puede poner un campo para con el nombre de la lista a la que la gente se ha "suscrito" algo así como
"To: boletin-novedades@mipagina.com"
y en el Bcc la lista real de destinatarios. La direccion boletin-novedades puede existir y recoger copias de los boletines, por ejemplo.

-A la pregunta de si se pueden personalizar lo emails: sí. La manera de hacerlo es definir el mensaje HTML como una variable a trozos. Entonces puedes ir extrayendo de la base de datos lo que quieres que aparezca, y luego se imprime esa variable en el lugar excato que quieras (intercalado en la posición, en el trozo que quieras del manesaje). Luego donde se definen los parámetros del mensaje, en el cuerpo pon la variable que define el mensaje(que está troceada) y ya está.

-¿Se pueden enviar emails en php? No, me temo que no se puede, ya que los gestores de correo no pueden leer PHP.

-¿Qué pasa con las comillas del del cuerpo del mensaje en HTML? Para que no de error, hay que poner una barra invertida: antes de cada comilla, véase: "

-Respecto a lo de tumbar el servidor y enviar uno por uno los mensajes: si se define un sistema mediante el que se envían uno por uno los mensajes, como proponían algunos lectores, lo que se está haciendo es ejecutar la función mail como un bucle a veces interminable, con lo que el tiempo de ejecución de la acción se alarga mucho y suele dar este error "Error en el tiempo de ejecución", que quiere decir que se ha sobrepasado el límite de tiempo de ejecución, además de los problemas de tumbar el servidor, como comentaba otro usuario.

-Por último, tal y como indica otro lector, este sistema sirve para cantidades asequibles de usuarios (depende de cada servidor) pero para cantidades masivas puede resultar engorroso. Un usuario nos sugiere que para tales efectos quizás sea mejor utilizar un programa auxiliar como Advanced Mass Sender.

Espero haberles servido de ayuda.
Un saludo a todos,
Atte. Raúl Avilés
Email: raul.aviles@gmail.com

Helsingius

22/2/2009
De verdad, falta aun el codigo php para incribirse, y un panel de control. No creo que sea muy util el mensaje si no es completo

Estibens

04/6/2010
No llegan los correos
Holas estaba probando el codigo emprime el mensaje de enviado con exito pero no les llega el correo

yonatan92

04/8/2011
Error
olle me sale este error, no se si me puedes ayudar

Warning: mail() [function.mail]: Failed to connect to mailserver at "localhost" port 25, verify your "SMTP" and "smtp_port" setting in php.ini or use ini_set() in D:xampphtdocsaemil.php on line 85
Error al Enviar el Email

Adrian

09/4/2012
Posible mejora
al parecer siempre envia a todos los correos con una coma al final pero cuando se ejecuta no llega al ultimo correo de la base de datos o si nomas hay uno no llega, eso es por que aparece la coma y la forma de quitarlo seria esta

$mails = trim($losemails, '');
echo $mails;

poner $mails en vez de donde va $losemails

emmanuel

27/5/2013
articulo
saludo