Confirmar un registro, recuperar una contraseña, avisar de un pedido: casi toda aplicación web necesita enviar correos. Y casi todos los principiantes tropiezan con lo mismo: el correo “se envía” pero nunca llega, o llega a la carpeta de spam. En el libro PHP desde cero hasta experto el envío de correos tiene su propio capítulo; aquí tienes la forma fiable de hacerlo con PHPMailer.
Por qué no usar mail()
PHP trae la función mail(), pero tiene problemas serios en la práctica:
- Depende de que el servidor tenga configurado un agente de correo. En XAMPP, por defecto, no lo tiene.
- No se autentica contra un servidor SMTP, así que los proveedores de correo desconfían de esos mensajes.
- Construir a mano correos HTML con adjuntos y codificación correcta es propenso a errores.
PHPMailer resuelve todo eso: se conecta a un servidor SMTP real (el de tu hosting, Gmail, Microsoft 365 o un servicio transaccional) y arma el mensaje correctamente.
Instalar PHPMailer con Composer
$ composer require phpmailer/phpmailer
Composer descarga la librería en la carpeta vendor/ y genera el archivo
vendor/autoload.php, que carga las clases automáticamente. Si no usas Composer, PHPMailer
también puede incluirse a mano, pero Composer es el estándar actual en PHP.
Ejemplo: enviar un correo HTML por SMTP
<?php
declare(strict_types=1);
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\PHPMailer;
require __DIR__ . '/vendor/autoload.php';
$config = require __DIR__ . '/config/correo.php'; // credenciales fuera del código
function enviarCorreo(array $config, string $para, string $asunto, string $html, string $texto): bool
{
$mail = new PHPMailer(true); // true = lanza excepciones si falla
try {
$mail->isSMTP();
$mail->Host = $config['host'];
$mail->SMTPAuth = true;
$mail->Username = $config['usuario'];
$mail->Password = $config['clave'];
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;
$mail->CharSet = PHPMailer::CHARSET_UTF8; // tildes y eñes correctas
$mail->setFrom($config['remitente'], 'Mi Aplicación');
$mail->addAddress($para);
$mail->isHTML(true);
$mail->Subject = $asunto;
$mail->Body = $html;
$mail->AltBody = $texto; // versión en texto plano
$mail->send();
return true;
} catch (Exception $e) {
error_log('Error al enviar correo: ' . $mail->ErrorInfo);
return false;
}
}
$ok = enviarCorreo(
$config,
'cliente@ejemplo.com',
'Confirma tu cuenta',
'<h1>¡Bienvenida!</h1><p>Gracias por registrarte.</p>',
"¡Bienvenida!\nGracias por registrarte."
);
echo $ok ? 'Correo enviado' : 'No se pudo enviar el correo';
<?php
return [
'host' => 'smtp.tu-proveedor.com',
'usuario' => 'no-responder@tudominio.com',
'clave' => 'contraseña-de-aplicación',
'remitente' => 'no-responder@tudominio.com',
];
Adjuntos
<?php
$mail->addAttachment(__DIR__ . '/facturas/factura-1024.pdf', 'Factura 1024.pdf');
Plantillas y datos del usuario
Mezclar HTML dentro de strings de PHP se vuelve inmanejable rápido. Una solución simple es guardar la plantilla en un archivo aparte y rellenarla con los datos, escapados:
<?php
function renderizarPlantilla(string $archivo, array $datos): string
{
$seguros = array_map(fn($v) => htmlspecialchars((string) $v, ENT_QUOTES, 'UTF-8'), $datos);
$html = file_get_contents($archivo); // contiene marcadores como {{nombre}}
foreach ($seguros as $clave => $valor) {
$html = str_replace('{{' . $clave . '}}', $valor, $html);
}
return $html;
}
$html = renderizarPlantilla(__DIR__ . '/plantillas/bienvenida.html', ['nombre' => $nombre]);
Escapar importa también en los correos: si el nombre del usuario contiene HTML, podría alterar el mensaje o insertar enlaces engañosos.
Que tus correos no lleguen a spam
- Envía desde tu dominio, no desde una dirección gratuita, y con el SMTP autorizado para ese dominio.
- Configura SPF, DKIM y DMARC en el DNS de tu dominio: son los registros que demuestran que tu servidor puede enviar en nombre de ese dominio.
- Incluye siempre versión en texto plano (
AltBody). - Evita asuntos alarmistas y mensajes que sean solo una imagen.
- Para volúmenes altos, usa un servicio de correo transaccional en lugar del SMTP del hosting compartido.
- No envíes en la misma petición si son muchos: guarda los correos en una cola y envíalos con una tarea programada.
El uso más habitual de todo esto es el flujo de “olvidé mi contraseña”, que construimos paso a paso en recuperación de contraseña con tokens seguros.
Correos automatizados en tus proyectos
El libro PHP desde cero hasta experto enseña a enviar correos electrónicos automatizados, como confirmaciones de registro y recuperación de contraseña.
Comprar en Amazon