Aunque hay partes de esta respuesta que se aplican solo al uso de la mail()
función en sí, muchos de estos pasos de solución de problemas se pueden aplicar a cualquier sistema de correo PHP.
Hay una variedad de razones por las cuales su script parece no enviar correos electrónicos. Es difícil diagnosticar estas cosas a menos que haya un error de sintaxis obvio. Sin uno, debe revisar la lista de verificación a continuación para encontrar posibles dificultades que pueda encontrar.
Asegúrese de que el informe de errores esté habilitado y configurado para informar todos los errores
El informe de errores es esencial para eliminar los errores en su código y los errores generales que PHP encuentra. El informe de errores debe estar habilitado para recibir estos errores. Colocar el siguiente código en la parte superior de sus archivos PHP (o en un archivo de configuración maestro) habilitará el informe de errores.
error_reporting(-1);
ini_set('display_errors', 'On');
set_error_handler("var_dump");
Consulte ¿Cómo puedo obtener mensajes de error útiles en PHP? - esta respuesta para más detalles sobre esto.
Asegúrese de que la mail()
función se llame
Puede parecer tonto, pero un error común es olvidar colocar la mail()
función en su código. Asegúrate de que esté allí y no comentado.
Asegúrese de que la mail()
función se llame correctamente
bool mail (cadena $ a, cadena $ asunto, cadena $ mensaje [, cadena $ Additional_headers [, cadena $ Additional_parameters]])
La función de correo toma tres parámetros requeridos y opcionalmente un cuarto y quinto. Si su llamada a mail()
no tiene al menos tres parámetros, fallará.
Si su llamada a mail()
no tiene los parámetros correctos en el orden correcto, también fallará.
Verifique los registros de correo del servidor
Su servidor web debería estar registrando todos los intentos de enviar correos electrónicos a través de él. La ubicación de estos registros variará (es posible que deba preguntar al administrador del servidor dónde se encuentran), pero comúnmente se pueden encontrar en el directorio raíz de un usuario en logs
. Dentro habrá mensajes de error que el servidor informó, si los hay, relacionados con sus intentos de enviar correos electrónicos.
Verifique la falla de conexión del puerto
El bloqueo de puertos es un problema muy común que enfrentan la mayoría de los desarrolladores al integrar su código para entregar correos electrónicos utilizando SMTP. Y esto se puede rastrear fácilmente en los registros de correo del servidor (la ubicación del servidor del registro de correo puede variar de un servidor a otro, como se explicó anteriormente). En caso de que esté en un servidor de alojamiento compartido, los puertos 25 y 587 permanecen bloqueados de forma predeterminada. Este bloqueo ha sido hecho a propósito por su proveedor de alojamiento. Esto es cierto incluso para algunos de los servidores dedicados. Cuando estos puertos estén bloqueados, intente conectarse usando el puerto 2525. Si encuentra que ese puerto también está bloqueado, entonces la única solución es contactar a su proveedor de alojamiento para desbloquear estos puertos.
La mayoría de los proveedores de alojamiento bloquean estos puertos de correo electrónico para proteger su red de enviar correos electrónicos no deseados.
Use los puertos 25 o 587 para conexiones simples / TLS y el puerto 465 para conexiones SSL. Para la mayoría de los usuarios, se sugiere utilizar el puerto 587 para evitar los límites de velocidad establecidos por algunos proveedores de alojamiento.
No use el operador de supresión de errores
Cuando el operador de supresión de errores @
se antepone a una expresión en PHP, cualquier mensaje de error que pueda generar esa expresión se ignorará. Hay circunstancias en las que es necesario usar este operador, pero el envío de correo no es una de ellas.
Si su código contiene @mail(...)
, puede estar ocultando mensajes de error importantes que lo ayudarán a depurar esto. Elimine @
y vea si se informa algún error.
Solo es aconsejable cuando verificaerror_get_last()
inmediatamente después de fallas concretas.
Verifique el mail()
valor de retorno
La mail()
función:
Devuelve TRUE
si el correo fue aceptado con éxito para la entrega, de lo FALSE
contrario. Es importante tener en cuenta que solo porque el correo fue aceptado para la entrega, NO significa que el correo realmente llegará al destino previsto.
Es importante tener en cuenta esto porque:
- Si recibe un
FALSE
valor de devolución, sabe que el error radica en que su servidor acepta su correo. Esto probablemente no sea un problema de codificación, sino un problema de configuración del servidor. Debe hablar con el administrador del sistema para averiguar por qué sucede esto.
- Si recibe un
TRUE
valor de devolución, no significa que su correo electrónico será enviado definitivamente. Simplemente significa que el correo electrónico fue enviado a su controlador respectivo en el servidor con éxito por PHP. Todavía hay más puntos de falla fuera del control de PHP que pueden hacer que el correo electrónico no se envíe.
Por FALSE
lo tanto, le ayudará a orientarlo en la dirección correcta, TRUE
aunque no necesariamente significa que su correo electrónico se haya enviado correctamente. ¡Esto es importante tener en cuenta!
Asegúrese de que su proveedor de alojamiento le permita enviar correos electrónicos y no limite el envío de correos
Muchos servidores web compartidos, especialmente los proveedores de alojamiento web gratuitos, no permiten que se envíen correos electrónicos desde sus servidores o limitan la cantidad que se puede enviar durante un período de tiempo determinado. Esto se debe a sus esfuerzos para limitar el envío de spammers de sus servicios más baratos.
Si cree que su host tiene límites de correo electrónico o bloquea el envío de correos electrónicos, consulte sus Preguntas frecuentes para ver si enumeran dichas limitaciones. De lo contrario, es posible que deba comunicarse con su soporte para verificar si existen restricciones en el envío de correos electrónicos.
Verificar carpetas de spam; evitar que los correos electrónicos se marquen como spam
A menudo, por varias razones, los correos electrónicos enviados a través de PHP (y otros lenguajes de programación del lado del servidor) terminan en la carpeta de correo no deseado del destinatario. Siempre verifique allí antes de solucionar su código.
Para evitar que el correo enviado a través de PHP se envíe a la carpeta de correo no deseado del destinatario, hay varias cosas que puede hacer, tanto en su código PHP como de otro modo, para minimizar las posibilidades de que sus correos electrónicos se marquen como correo no deseado. Los buenos consejos de Michiel de Mare incluyen:
- Use métodos de autenticación de correo electrónico, como SPF y DKIM para demostrar que sus correos electrónicos y su nombre de dominio pertenecen juntos, y para evitar la falsificación de su nombre de dominio. El sitio web de SPF incluye un asistente para generar la información de DNS para su sitio.
- Verifique su DNS inverso para asegurarse de que la dirección IP de su servidor de correo apunte al nombre de dominio que utiliza para enviar correo.
- Asegúrese de que la dirección IP que está utilizando no esté en una lista negra
- Asegúrese de que la dirección de respuesta sea una dirección válida y existente.
- Utilice el nombre completo y real del destinatario en el campo Para, no solo la dirección de correo electrónico (p
"John Smith" <john@blacksmiths-international.com>
. Ej .).
- Controle sus cuentas de abuso, como abuse@yourdomain.com y postmaster@yourdomain.com. Eso significa: asegúrese de que existan estas cuentas, lea lo que se les envía y actúe sobre las quejas.
- Finalmente, haga que sea muy fácil darse de baja. De lo contrario, sus usuarios se darán de baja presionando el botón de spam y eso afectará su reputación.
Consulte ¿Cómo se asegura de que el correo electrónico que envía mediante programación no se marque automáticamente como correo no deseado? para más sobre este tema
Asegúrese de que se suministren todos los encabezados de correo
Algunos programas de spam rechazarán el correo si faltan encabezados comunes como "De" y "Responder a":
$headers = array("From: from@example.com",
"Reply-To: replyto@example.com",
"X-Mailer: PHP/" . PHP_VERSION
);
$headers = implode("\r\n", $headers);
mail($to, $subject, $message, $headers);
Asegúrese de que los encabezados de correo no tengan errores de sintaxis
Los encabezados inválidos son tan malos como no tener encabezados. Un carácter incorrecto podría ser todo lo que se necesita para descarrilar su correo electrónico. Vuelva a verificar para asegurarse de que su sintaxis sea correcta, ya que PHP no detectará estos errores por usted.
$headers = array("From from@example.com", // missing colon
"Reply To: replyto@example.com", // missing hyphen
"X-Mailer: "PHP"/" . PHP_VERSION // bad quotes
);
No use un From:
remitente falso
Si bien el correo debe tener un remitente De, no solo puede usar cualquier valor. En particular, las direcciones de remitente divididas por el usuario son una forma segura de bloquear los correos:
$headers = array("From: $_POST[contactform_sender_email]"); // No!
Motivo: su servidor de correo web o de envío no está en la lista blanca SPF / DKIM para pretender ser responsable de las direcciones @hotmail o @gmail. Incluso puede soltar silenciosamente correos con From:
dominios de remitente para los que no está configurado.
Asegúrese de que el valor del destinatario sea correcto
A veces, el problema es tan simple como tener un valor incorrecto para el destinatario del correo electrónico. Esto puede deberse al uso de una variable incorrecta.
$to = 'user@example.com';
// other variables ....
mail($recipient, $subject, $message, $headers); // $recipient should be $to
Otra forma de probar esto es codificar el valor del destinatario en la mail()
llamada de función:
mail('user@example.com', $subject, $message, $headers);
Esto puede aplicarse a todos los mail()
parámetros.
Enviar a varias cuentas
Para ayudar a descartar problemas con la cuenta de correo electrónico, envíe su correo electrónico a varias cuentas de correo electrónico en diferentes proveedores de correo electrónico . Si sus correos electrónicos no llegan a la cuenta de Gmail de un usuario, envíe los mismos correos electrónicos a una cuenta de Yahoo, una cuenta de Hotmail y una cuenta POP3 normal (como su cuenta de correo electrónico proporcionada por el ISP).
Si los correos electrónicos llegan a todas o algunas de las otras cuentas de correo electrónico, usted sabe que su código está enviando correos electrónicos, pero es probable que el proveedor de la cuenta de correo electrónico los esté bloqueando por alguna razón. Si el correo electrónico no llega a ninguna cuenta de correo electrónico, es más probable que el problema esté relacionado con su código.
Asegúrese de que el código coincida con el método del formulario
Si ha configurado su método de formulario en POST
, asegúrese de que está utilizando $_POST
para buscar sus valores de formulario. Si lo configuró GET
o no lo configuró, asegúrese de usarlo $_GET
para buscar los valores de su formulario.
Asegúrese de que el action
valor de su formulario apunte a la ubicación correcta
Asegúrese de que su action
atributo de formulario contenga un valor que apunte a su código de correo PHP.
<form action="send_email.php" method="POST">
Asegúrese de que el proveedor de alojamiento web admita el envío de correo electrónico
Algunos proveedores de alojamiento web no permiten ni habilitan el envío de correos electrónicos a través de sus servidores. Las razones para esto pueden variar, pero si han deshabilitado el envío de correo, deberá utilizar un método alternativo que utilice un tercero para enviarle esos correos electrónicos.
Un correo electrónico a su soporte técnico (después de un viaje a su soporte en línea o preguntas frecuentes) debe aclarar si las capacidades de correo electrónico están disponibles en su servidor.
Asegúrese de que el localhost
servidor de correo esté configurado
Si está desarrollando en su estación de trabajo local usando WAMP, MAMP o XAMPP, probablemente no esté instalado un servidor de correo electrónico en su estación de trabajo. Sin uno, PHP no puede enviar correo por defecto.
Puede superar esto instalando un servidor de correo básico. Para Windows puede usar el Mercury Mail gratuito .
También puede usar SMTP para enviar sus correos electrónicos. Vea esta gran respuesta de Vikas Dwivedi para aprender cómo hacer esto.
Habilitar PHP personalizado mail.log
Además del archivo de registro de su MTA y PHP, puede habilitar el registro de la mail()
función específicamente. No registra la interacción SMTP completa, sino al menos los parámetros de llamada de función y el script de invocación.
ini_set("mail.log", "/tmp/mail.log");
ini_set("mail.add_x_header", TRUE);
Ver http://php.net/manual/en/mail.configuration.php para más detalles. (Es mejor habilitar estas opciones en php.ini
o .user.ini
o .htaccess
quizás).
Consulte con un servicio de prueba de correo
Hay varios servicios de entrega y verificación de spam que puede utilizar para probar su configuración de MTA / servidor web. Por lo general, envía una sonda de correo a: su dirección, luego obtiene un informe de entrega y más fallas concretas o análisis posteriores:
Use un correo diferente
La mail()
función incorporada de PHP es útil y a menudo hace el trabajo, pero tiene sus defectos . Afortunadamente, existen alternativas que ofrecen más potencia y flexibilidad, incluido el manejo de muchos de los problemas descritos anteriormente:
Todo lo cual se puede combinar con un servidor profesional SMTP / proveedor de servicios. (Debido a que los típicos planes de alojamiento web compartido del 15/08 son impredecibles cuando se trata de la configuración / configuración del correo electrónico).