W3docs

PHP Mail

Aprende a usar la función mail() de PHP para enviar correos electrónicos desde un script, con ejemplos de texto plano y HTML.

La función integrada mail() de PHP envía correos electrónicos directamente desde un script, sin necesidad de bibliotecas adicionales. Es la forma más rápida de enviar una notificación, un mensaje de "contáctanos" o un enlace de restablecimiento de contraseña. Este capítulo explica la firma de la función, muestra ejemplos de texto plano y HTML, y cubre los problemas de seguridad y entregabilidad más comunes en producción.

Qué hace la función mail()

mail() entrega un mensaje al agente de transferencia de correo (MTA) local del servidor — el programa (como Sendmail, Postfix o Exim) que se encarga de retransmitir el correo al mundo exterior. PHP no se comunica directamente con servidores SMTP remotos; simplemente pone el mensaje en cola localmente. Si el host no tiene un MTA funcionando, mail() devuelve false y no se envía nada.

La función devuelve un booleano: true si el mensaje fue aceptado para su entrega (no es lo mismo que entregado), y false en caso de error.

Sintaxis

mail(
    string $to,
    string $subject,
    string $message,
    array|string $additional_headers = [],
    string $additional_params = ""
): bool
ParámetroRequeridoDescripción
$toDirección(es) del destinatario. Separa múltiples direcciones con una coma.
$subjectLínea de asunto. No debe contener saltos de línea.
$messageEl cuerpo del correo. Las líneas deben separarse con \r\n y no superar los 70 caracteres.
$additional_headersNoCabeceras adicionales como From, Reply-To o Content-Type. A partir de PHP 7.2 puede ser un array asociativo.
$additional_paramsNoIndicadores de línea de comandos adicionales para el MTA (por ejemplo, el remitente del sobre mediante -f).

Enviar un correo de texto plano

Este es el caso más común: un mensaje de texto simple con algunas cabeceras.

<?php
$to      = '[email protected]';
$subject = 'Test email';
$message = 'This is a test email from PHP.';

// Additional headers
$headers  = 'From: [email protected]' . "\r\n";
$headers .= 'Reply-To: [email protected]' . "\r\n";
$headers .= 'X-Mailer: PHP/' . phpversion();

if (mail($to, $subject, $message, $headers)) {
    echo 'Email sent successfully.';
} else {
    echo 'Failed to send email.';
}
?>

Definimos el destinatario, el asunto y el cuerpo, y luego construimos una cadena de cabeceras. La cabecera From identifica al remitente, Reply-To controla a dónde van las respuestas, y X-Mailer es informativa. Las cabeceras se unen con \r\n (retorno de carro + salto de línea), que es el terminador de línea que requiere el protocolo de correo.

Enviar un correo HTML

Para enviar HTML con formato, agrega Content-type: text/html a las cabeceras. Sin esto, el destinatario verá las etiquetas en crudo en lugar del marcado renderizado.

<?php
$to      = '[email protected]';
$subject = 'HTML email';
$message = '
<html>
<body>
    <h1>Hello!</h1>
    <p>This message is <strong>formatted with HTML</strong>.</p>
</body>
</html>';

// To send HTML mail, the Content-type header must be set
$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=UTF-8' . "\r\n";
$headers .= 'From: [email protected]' . "\r\n";

mail($to, $subject, $message, $headers);
?>

Enviar a múltiples destinatarios

Pasa una lista separada por comas en $to, o usa las cabeceras Cc/Bcc:

<?php
$to      = '[email protected], [email protected]';
$subject = 'Team update';
$message = 'Meeting moved to 3 PM.';

$headers  = 'From: [email protected]' . "\r\n";
$headers .= 'Bcc: [email protected]' . "\r\n";

mail($to, $subject, $message, $headers);
?>

Protección contra inyección de cabeceras

Si cualquier parte de una cabecera — especialmente From o Reply-To — proviene de la entrada del usuario (como un formulario de contacto), un atacante puede inyectar saltos de línea adicionales para añadir sus propias cabeceras y convertir tu script en un repetidor de spam. Nunca pongas entrada de usuario sin procesar en las cabeceras. Valida y sanea primero:

<?php
// $_POST['email'] comes from an untrusted form
$email = filter_var($_POST['email'] ?? '', FILTER_VALIDATE_EMAIL);

if ($email === false) {
    exit('Invalid email address.');
}

// Strip any line breaks that could be used to inject headers
$email = str_replace(["\r", "\n"], '', $email);

$headers = 'From: ' . $email . "\r\n";
mail('[email protected]', 'Contact form', 'New message', $headers);
?>

Consulta filter_var() y el capítulo PHP Filter para más información sobre la validación de entradas, y PHP Form Validation para manejar datos de formularios de forma segura.

Entregabilidad y notas de producción

Nota: La función mail() depende del MTA local del servidor. En muchos entornos de alojamiento modernos, falla silenciosamente o acaba en la carpeta de spam sin la configuración adecuada. Para aplicaciones reales, es preferible usar una biblioteca consolidada como PHPMailer o Symfony Mailer, que admiten autenticación SMTP, archivos adjuntos, codificación y colas. Sea cual sea la opción elegida, configura registros válidos de SPF, DKIM y DMARC para tu dominio, de modo que los proveedores de buzones de correo confíen en tus mensajes.

Un true devuelto solo significa que el MTA aceptó el mensaje — no es una confirmación de entrega. Para rastrear la entrega real, los rebotes y las aperturas, utiliza un servicio de correo transaccional.

Casos de uso comunes

  • Formularios de contacto — recopila un mensaje y envíalo por correo al propietario del sitio (combínalo con PHP Form Handling).
  • Notificaciones — confirmaciones de pedidos, alertas, restablecimientos de contraseña.
  • Informes — scripts programados que envían un resumen por correo.

Conclusión

La función mail() de PHP ofrece una forma rápida y sin dependencias para enviar correo desde un script: proporciona el destinatario, el asunto y el cuerpo, y luego añade cabeceras para el remitente, la dirección de respuesta o el contenido HTML. Ten en cuenta sus limitaciones — depende de un MTA configurado, devuelve la aceptación en lugar de la entrega, y nunca debe recibir entrada de usuario sin sanear en sus cabeceras. Para cualquier cosa más allá del correo simple y de bajo volumen, recurre a una biblioteca especializada. Para seguir aprendiendo, explora PHP Functions y PHP Strings.

Práctica

Práctica
¿Cuáles son los parámetros de la función mail() de PHP?
¿Cuáles son los parámetros de la función mail() de PHP?
Was this page helpful?