En este post se explica cómo enviar un correo electrónico, desde PHP, a cualquier dirección de correo electrónico. Por ejemplo, enviar desde PHP un mail a tu_usuario@gmail.com o cualquier dominio, así como si lo enviáramos a mano.
Lo que se verá es:
- Enviar un correo desde PHP
- Poner un asunto incluso si el mismo tiene letras con acentos
- Establecer el remitente a un nombre personalizado
- Cortar el mensaje para evitar truncarlo
- Enviar HTML a través de un correo
Este tutorial será muy sencillo y simple para que se pueda apreciar lo básico para enviar un correo con PHP usando la función mail.
Cómo funciona el envío de correos desde PHP
Hace algún tiempo, en mis inicios de esto de la programación, no sabía cómo funcionaba el envío de correo, ni los servidores, ni PHP; nada. Y en una ocasión alguien me pidió algo muy simple: un formulario de contacto, en donde el mensaje que un visitante enviara le llegara por correo. Justo ahora, lo podría hacer en 10 minutos, pero en aquellos tiempos no.
El punto es que voy a responder aquí unas dudas que tal vez como principiantes tengamos:
¿Es fácil? claro que sí, es llamar a una función, pasarle argumentos y listo
¿Cómo sé si el mensaje se envió? la función devuelve un booleano indicando si se envió o no
¿Cómo sé si el mensaje llegó? eso es más difícil de saber, porque a veces los filtros de correo marcan a nuestros mensajes como spam; pero bueno, puedes probar primero enviando un mensaje a tu correo personal.
¿Puedo enviar correos a cualquier dirección? claro, no importa si es gmail, hotmail o de un dominio personalizado.
¿PHP ya viene con un servidor de correos? No. Tú tienes que instalar un servidor de correos, lo cual es una historia aparte; pero tengo buenas noticias para ti: en el mundo del desarrollo web, la mayoría de veces se programa en un hosting compartido; que es un servidor que compartes con otras personas que ya tiene todo configurado e instalado; PHP, apache y esas cosas; incluso un servidor de correos. Está listo para enviar correos electrónicos y para que le pongas tus scripts.
En caso de que no tengas un hosting compartido, no te preocupes; pronto traeré un tutorial de cómo instalar un servidor de correos en Linux.
Requisitos y recomendaciones
Antes de comenzar, recuerda tener instalado PHP y Apache con XAMPP. Igualmente te recomiendo que instales este programa para ver los correos que se envían, en lugar de ocupar tu dirección verdadera.
Enviar correo electrónico
La forma más simple es poner, en un script de PHP lo siguiente:
<?php
/*
Enviar correo desde PHP con mail
*/
$resultado = mail("tu_correo@dominio.com", "Yo soy el asunto del correo", "Yo soy el mensaje");
if ($resultado) {
echo "El correo fue enviado";
} else {
echo "El correo no fue enviado";
}
Si lo pones en un servidor que tenga un servidor de correo instalado, o desde tu PC con el programa que dejé al inicio, verás que el correo se envía (obviamente poniendo una dirección real). Eso es lo mínimo que necesitas para enviar un correo con PHP.
Ahora que ya comprobaste que se pudo (revisa la carpeta de spam si lo enviaste a una dirección) es hora de hacer cosas un poco más avanzadas; no tan avanzadas, pero verás que son interesantes.
Poner asunto con caracteres especiales
Esto me pasó en producción alguna vez. El asunto era algo como “Activación de tu cuenta en bla bla”. Lo que pasaba era que la o acentuada o con tilde no se mostraba; investigando un poco encontré una función que se encarga de arreglar esto.
Lo que se hace es codificar el encabezado o algo así, la función queda de la siguiente manera:
<?php
function limpiarAsunto($asunto)
{
$cadena = "Subject";
$longitud = strlen($cadena) + 2;
return substr(
iconv_mime_encode(
$cadena,
$asunto,
[
"input-charset" => "UTF-8",
"output-charset" => "UTF-8",
]
),
$longitud
);
}
echo limpiarAsunto("Activación de tu cuenta para bla bla");
?>
Usamos substr
porque la función regresa una cadena que tiene “Subject: “, y no queremos eso, queremos lo que sigue después.
Para usar esta función, hacemos esto:
mail("correo@dominio.com", limpiarAsunto("El asunto del correo"), "El mensaje" );
Establecer el remitente a un nombre personalizado
Otra de las cosas que son necesarias al enviar un correo electrónico es poner un remitente personalizado; que aunque nuestro dominio sea parzibyte.me, en el remitente diga “Luis Cabrera” (por ejemplo). Para ello, ponemos algunos encabezados separados por \r\n y los mandamos como cuarto argumento:
<?php
function limpiarAsunto($asunto)
{
$cadena = "Subject";
$longitud = strlen($cadena) + 2;
return substr(
iconv_mime_encode(
$cadena,
$asunto,
[
"input-charset" => "UTF-8",
"output-charset" => "UTF-8",
]
),
$longitud
);
}
$asunto = limpiarAsunto("Boletín semanal");
$destinatario = "staff@gmail.com";
$encabezados = "MIME-Version: 1.0" . "\r\n";
# ojo, es una concatenación:
$encabezados .= 'From: Luis Cabrera<contacto@parzibyte.me>' . "\r\n";
$mensaje = "Hola, este es un mensaje";
$resultado = mail($destinatario, $asunto, $mensaje, $encabezados); #Mandar al final los encabezados
if ($resultado) {
echo "Correo enviado";
} else {
echo "Correo NO enviado";
}
Es un poco complicado al inicio, pero no tanto. Lo importante es que si mandamos más encabezados, los separemos con \r\n.
Aquí estamos enviando la versión de MIME y también el remitente, puedes cambiarlo si gustas, pero en el correo pon uno de tu dominio. En mi caso el correo llega así:
Ahí mismo se ve que aunque el asunto tiene acentos, los mismos se muestran correctamente.
Cortar el mensaje para evitar truncarlo
El texto del mensaje debe ir separado en líneas de 70 caracteres. Para ello ya existe una función llamada wordwrap:
$mensaje = wordwrap($mensaje, 70, "\r\n");
Enviar HTML
Actualización: si experimentas errores enviando HTML, omite la parte en donde cortas el mensaje con wordwrap
; manda directamente todo el contenido, sin saltos de línea ni cortes.
Para terminar y poner todo junto, vamos a enviar un correo electrónico con un poco de HTML. El código es este:
<?php
function limpiarAsunto($asunto)
{
$cadena = "Subject";
$longitud = strlen($cadena) + 2;
return substr(
iconv_mime_encode(
$cadena,
$asunto,
[
"input-charset" => "UTF-8",
"output-charset" => "UTF-8",
]
),
$longitud
);
}
$asunto = limpiarAsunto("Boletín semanal");
$destinatario = "staff@gmail.com";
$encabezados = "MIME-Version: 1.0" . "\r\n";
# ojo, es una concatenación:
$encabezados .= "Content-type:text/html; charset=UTF-8" . "\r\n";
$encabezados .= 'From: Luis Cabrera<contacto@parzibyte.me>' . "\r\n";
$mensaje = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Este es un mensaje</title>
<style type="text/css">
h1{
color: #8bc34a;
}
p{
font-size: 1rem;
}
img{
width: 10rem;
height: 10rem;
}
</style>
</head>
<body>
<h1>Este es un título con estilo</h1>
<p>Hola, mundo. Este es un mensaje largo</p>
<p>
También se pueden poner links: <a href="https://parzibyte.me/blog">parzibyte.me</a>,cosas
como <strong>negritas</strong> o <code>código</code>. Es decir, cualquier cosa que tenga que ver con HTML
puede enviarse en los correos.
</p>
<h1>Una imagen...</h1>
<img src="https://github.com/parzibyte.png">
</body>';
$mensaje = wordwrap($mensaje, 70, "\r\n");
$resultado = mail($destinatario, $asunto, $mensaje, $encabezados); #Mandar al final los encabezados
if ($resultado) {
echo "Correo enviado";
} else {
echo "Correo NO enviado";
}
Aunque su estructura se ve mal, funciona. Ya luego podemos mejorar eso con un motor de plantillas o separando conceptos; el punto es renderizar el HTML y los estilos, así como el mensaje.
Como se puede ver, agregamos estilos CSS en la etiqueta <head>
. Desafortunadamente para los programadores, y afortunadamente para el usuario final, no se pueden incluir estilos con una etiqueta <link>
. Esto es por la seguridad de que no se pueden incluir contenidos de enlaces externos.
El mensaje que llega es este:
Esa es la captura del programa que captura mensajes de correo, pero en Gmail se ve distinto, como en la captura del inicio.
Conclusión
Así de simple es enviar correos con PHP. Podemos enviar HTML, texto plano, imágenes, estilos y más cosas. Más adelante traeré ejemplos de cómo enviar adjuntos, prevenir inyecciones de encabezados, etcétera.
Si hay dudas ahí están los comentarios.
Pingback: Obtener IP de un usuario a través de un correo electrónico - Parzibyte's blog
Pingback: Configurar servidor SMTP para pruebas de PHP - Parzibyte's blog