mail()
Aprende a usar la función mail() de PHP para enviar correos electrónicos desde un script, con sintaxis, parámetros y consejos de seguridad.
La función mail() envía mensajes de correo electrónico directamente desde un script PHP. Es la forma más sencilla integrada de enviar correo, y esta guía cubre su sintaxis y parámetros, cómo funcionan las cabeceras, el envío de mensajes HTML y a múltiples destinatarios, los riesgos de seguridad que hay que evitar y cuándo conviene utilizar una librería dedicada.
¿Qué es la función mail()?
La función mail() es una función integrada de PHP que entrega un correo electrónico al agente de transferencia de correo (MTA) del sistema — normalmente sendmail en Linux — o al servidor SMTP configurado en php.ini. Como depende de esa configuración local, mail() frecuentemente devuelve false (o falla silenciosamente al entregar) en una máquina de desarrollo que no tiene ningún MTA instalado. No abre una conexión SMTP por sí misma, por lo que no puede autenticarse contra un proveedor externo como Gmail.
Un valor de retorno true solo significa que el mensaje fue aceptado para su entrega por el MTA — no es una garantía de que el correo llegó a la bandeja de entrada del destinatario.
Sintaxis
mail(
string $to,
string $subject,
string $message,
array|string $additional_headers = [],
string $additional_params = ""
): bool| Parámetro | Requerido | Descripción |
|---|---|---|
$to | Sí | Dirección(es) del destinatario. Varias direcciones separadas por comas, p. ej. "[email protected], [email protected]". |
$subject | Sí | La línea de asunto. No debe contener saltos de línea. |
$message | Sí | El cuerpo. Cada línea debe separarse con \r\n y no debe superar los 70 caracteres. |
$additional_headers | No | Cabeceras adicionales como From, Cc, Bcc, Content-Type. Una cadena (separada por CRLF) o, desde PHP 7.2, un array asociativo. |
$additional_params | No | Flags adicionales que se pasan a la línea de comandos del MTA (p. ej. -f para establecer el remitente del sobre). |
Cómo usar la función mail()
A continuación se muestra un ejemplo completo de texto plano que construye las cabeceras y comprueba el valor de retorno:
<?php
$to = '[email protected]';
$subject = 'Test email';
$message = 'This is a test email from PHP';
// Additional headers
$headers = 'From: [email protected]' . "\r\n"
. 'Reply-To: [email protected]' . "\r\n"
. 'X-Mailer: PHP/' . phpversion();
// Send the email and check the result
if (mail($to, $subject, $message, $headers)) {
echo "Email sent successfully.";
} else {
echo "Email delivery failed.";
}
?>Definimos el destinatario, el asunto y el mensaje, y luego construimos las cabeceras. Como mail() devuelve un booleano, es una buena práctica comprobar el valor de retorno en lugar de asumir que el envío fue exitoso. La cabecera From es importante: sin ella, muchos servidores de correo rechazan el mensaje o lo marcan como spam.
Enviar un correo HTML
Para enviar HTML en lugar de texto plano, añade Content-Type: text/html a las cabeceras. Sin ello, el cliente muestra las etiquetas en crudo como texto.
<?php
$to = '[email protected]';
$subject = 'HTML email test';
$message = '<h1>Hello</h1><p>This message is <b>HTML</b>.</p>';
$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);
?>Múltiples destinatarios, Cc y Bcc
Incluye varias direcciones en $to (separadas por comas) para la línea "Para" visible, y usa las cabeceras Cc/Bcc para las copias:
<?php
$to = '[email protected], [email protected]';
$subject = 'Team update';
$message = 'See attached agenda.';
$headers = "From: [email protected]\r\n";
$headers .= "Cc: [email protected]\r\n";
$headers .= "Bcc: [email protected]\r\n";
mail($to, $subject, $message, $headers);
?>Los destinatarios en Bcc son invisibles para todos los demás, mientras que las direcciones en Cc son visibles para todos los destinatarios.
Seguridad: evitar la inyección de cabeceras
Si alguna parte del destinatario, el asunto o las cabeceras proviene de la entrada del usuario — por ejemplo, un formulario de contacto — un atacante puede inyectar saltos de línea adicionales para agregar sus propias cabeceras Cc/Bcc y usar tu servidor para enviar spam. Siempre valida las direcciones y elimina los saltos de línea antes de pasarlos a mail():
<?php
$email = $_POST['email'] ?? '';
// Reject anything that is not a valid email address
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
exit('Invalid email address.');
}
// Strip CR/LF so the value can't inject new headers
$email = str_replace(["\r", "\n"], '', $email);
?>Usa filter_var() con FILTER_VALIDATE_EMAIL para validar, y consulta Validación de formularios PHP y Manejo de URL/correo en formularios para conocer patrones seguros de procesamiento de formularios.
Limitaciones y cuándo usar una librería
mail() es adecuado para mensajes simples de bajo volumen, pero tiene limitaciones reales:
- No puede autenticarse contra un servidor SMTP externo (sin usuario/contraseña, sin negociación TLS).
- No ofrece soporte nativo para adjuntos — debes construir las partes MIME manualmente.
- El reporte de errores es mínimo: un retorno
falsete dice muy poco sobre por qué falló la entrega.
Para producción, correo transaccional o cualquier cosa con adjuntos, utiliza una librería dedicada como PHPMailer o Symfony Mailer. Estas gestionan la autenticación SMTP, la codificación, los adjuntos y un reporte de errores mucho más completo.
Conclusión
La función mail() proporciona una forma rápida de enviar correo electrónico directamente desde PHP y es adecuada para notificaciones sencillas cuando hay un MTA disponible. Recuerda que su éxito depende de la configuración del servidor, que debes protegerte contra la inyección de cabeceras con datos proporcionados por el usuario, y que los sistemas en producción generalmente se benefician más de PHPMailer o Symfony Mailer. Para lectura relacionada, explora Funciones PHP y la función header().