La función de correo PHP no completa el envío de correo electrónico
Frecuentes
Visto 457,361 equipos
535
<?php
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = 'contact@yoursite.com';
$subject = 'Customer Inquiry';
$body = "From: $name\n E-Mail: $email\n Message:\n $message";
if ($_POST['submit']) {
if (mail ($to, $subject, $body, $from)) {
echo '<p>Your message has been sent!</p>';
} else {
echo '<p>Something went wrong, go back and try again!</p>';
}
}
?>
He intentado crear un formulario de correo simple. El formulario en sí está en mi index.html
pero se envía a una página separada de "gracias por su envío", thankyou.php
, donde está incrustado el código PHP anterior. El código se envía perfectamente, pero nunca envía un correo electrónico. ¿Cómo puedo arreglar esto?
29 Respuestas
582
Aunque hay partes de esta respuesta que se aplican solo al uso de lamail()
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 que su secuencia de comandos parece no estar enviando 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 errores en su código y errores generales que encuentra PHP. 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");
Ver ¿Cómo puedo obtener mensajes de error útiles en PHP? - esta respuesta para más detalles sobre esto
Asegúrese de que el mail()
se llama a la función
Puede parecer una tontería, pero un error común es olvidarse de colocar el mail()
función en su código. Asegúrate de que esté allí y no esté comentado.
Asegúrese de que el mail()
la función se llama correctamente
bool mail (cadena $para, cadena $asunto, cadena $mensaje [, cadena $encabezados_adicionales [, cadena $parámetros_adicionales]])
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 registrar todos los intentos de enviar correos electrónicos a través de él. La ubicación de estos registros variará (es posible que deba preguntarle al administrador del servidor dónde están ubicados), pero normalmente 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.
Compruebe si hay una falla en la conexión del puerto
El bloqueo de puertos es un problema muy común al que se enfrentan la mayoría de los desarrolladores al integrar su código para enviar correos electrónicos mediante SMTP. Y esto se puede rastrear fácilmente en los registros de correo del servidor (la ubicación del servidor de 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 por defecto. Este bloqueo ha sido realizado 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 ponerse en contacto con 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 del envío de correos electrónicos no deseados.
Utilice 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 usar el puerto 587 para evitar los límites de velocidad establecidos por algunos proveedores de alojamiento.
No utilice 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 será ignorado. Hay circunstancias en las que es necesario utilizar este operador pero el envío de correo es no uno de ellos.
Si su código contiene @mail(...)
entonces puede estar ocultando mensajes de error importantes que lo ayudarán a depurar esto. Quitar el @
y ver si se reportan errores.
Sólo es recomendable cuando Ud. Comprobar con error_get_last()
inmediatamente después por fallas concretas.
Asegúrate de leer mail()
valor de retorno
La mail()
función:
Retorno
TRUE
si el correo se aceptó con éxito para su entrega,FALSE
de lo contrario. Es importante tener en cuenta que el hecho de que el correo haya sido aceptado para la entrega NO significa que el correo realmente llegará al destino previsto.
Es importante tener esto en cuenta porque:
- Si recibe una
FALSE
valor de retorno, 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 una
TRUE
valor de retorno no significa que su correo electrónico definitivamente será enviado. Simplemente significa que PHP envió el correo electrónico a su respectivo controlador en el servidor con éxito. 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.
So FALSE
le ayudará a orientarlo en la dirección correcta, mientras que TRUE
sí no necesariamente significa que su correo electrónico fue enviado con éxito. ¡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 evitar que los spammers se aprovechen 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 torno al envío de correos electrónicos.
Verifique las carpetas de correo no deseado; evitar que los correos electrónicos se marquen como spam
A menudo, por diversas 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 problemas con su código.
Para evitar que el correo enviado a través de PHP se envíe a la carpeta de correo no deseado de un destinatario, hay varias cosas que puede hacer, tanto en su código PHP como de otra manera, para minimizar las posibilidades de que sus correos electrónicos se marquen como correo no deseado. Buenos consejos de Miguel de Mare incluyen:
- Utilice 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 van de la mano y para evitar la suplantación de su nombre de dominio. El sitio web de SPF incluye un asistente para generar la información de DNS para su sitio.
- Revise a tu 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 sea no en una lista negra
- Asegúrese de que la dirección de respuesta sea una dirección existente válida.
- Utilice el nombre completo y real del destinatario en el campo Para, no solo la dirección de correo electrónico (p. Ej.
"John Smith" <john@blacksmiths-international.com>
).- Supervise 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íe y actúe sobre las quejas.
- Finalmente, hazlo realmente fácil de cancelar la suscripción. De lo contrario, sus usuarios se darán de baja presionando el correo no deseado (spam) botón, y eso afectará su reputación.
Ver ¿Cómo se asegura de que el correo electrónico que envía mediante programación no se marque automáticamente como spam? para más información sobre este tema.
Asegúrese de que se proporcionen 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 no vá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. Verifique dos veces para asegurarse de que su sintaxis sea correcta, ya que PHP lo hará 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 uses un falso From:
remitente
Si bien el correo debe tener un remitente De:, no puede simplemente usar cualquier valor. En particular, las direcciones de remitente proporcionadas por el usuario son una forma segura de bloquear los correos:
$headers = array("From: $_POST[contactform_sender_email]"); // No!
Motivo: su servidor web o de envío de correo no está en la lista blanca de SPF/DKIM para pretender ser responsable de las direcciones de @hotmail o @gmail. Incluso puede dejar caer 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 el 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 la cuenta de correo electrónico proporcionada por su ISP).
Si los correos electrónicos llegan a todas o algunas de las otras cuentas de correo electrónico, sabrá 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 algún motivo. 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úrate de que el código coincida con el método del formulario.
Si ha establecido su método de formulario en POST
, asegúrese de estar usando $_POST
para buscar los valores de su formulario. Si lo ha configurado para GET
o no lo configuró en absoluto, asegúrese de usar $_GET
para buscar los valores de su formulario.
Asegúrese de que su formulario action
el valor apunta a la ubicación correcta
Asegúrese de que su formulario action
El atributo contiene un valor que apunta 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. Los motivos de esto pueden variar, pero si han deshabilitado el envío de correos, deberá utilizar un método alternativo que utilice un tercero para enviar esos correos electrónicos por usted.
Un correo electrónico a su soporte técnico (después de un viaje a su soporte en línea o preguntas frecuentes) debería aclarar si las capacidades de correo electrónico están disponibles en su servidor.
Asegúrese de que el localhost
el servidor de correo está configurado
Si está desarrollando en su estación de trabajo local utilizando WAMP, MAMP o XAMPP, es probable que no haya un servidor de correo electrónico instalado 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 la versión gratuita Correo de mercurio.
También puede usar SMTP para enviar sus correos electrónicos. Ver esta gran respuesta desde Vikas Dwivedi para aprender a hacer esto.
Habilitar la costumbre de PHP mail.log
Además del archivo de registro de su MTA y PHP, puede habilitar registro para el mail()
función específicamente. No registra la interacción SMTP completa, pero 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 detalles. (Es mejor habilitar estas opciones en el php.ini
or .user.ini
or .htaccess
quizás.)
Consulte con un servicio de prueba de correo
Hay varios servicios de verificación de entrega y spam que puede utilizar para probar la configuración de su 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 o análisis concretos más adelante:
- mail-tester.com (gratis/sencillo)
- glockapps.com (gratis/$$$)
- senforensics.com (registrarse/$$$)
- mailtrap.io (pro/$$$)
- ultratools/…/prueba de correo electrónico (gratis/solo cheques MX)
- Varios: http://www.verticalresponse.com/blog/7-email-testing-delivery-tools/
Usar un correo diferente
PHP incorporado mail()
La función es útil y, a menudo, hace el trabajo, pero tiene sus defectos. Afortunadamente, existen alternativas que ofrecen más poder y flexibilidad, incluido el manejo de muchos de los problemas descritos anteriormente:
- Ser más popular: PHPMailer
- Igualmente característico: SwiftMailer
- O incluso el mayor PEAR :: Correo.
Todo lo cual se puede combinar con un servidor/proveedor de servicios SMTP profesional. (Porque los planes típicos de alojamiento web compartido del 08/15 son impredecibles en lo que respecta a la configuración/configurabilidad del correo electrónico).
Respondido 01 Oct 20, 21:10
44
Agregue un encabezado de correo en la función de correo:
$header = "From: noreply@example.com\r\n";
$header.= "MIME-Version: 1.0\r\n";
$header.= "Content-Type: text/html; charset=ISO-8859-1\r\n";
$header.= "X-Priority: 1\r\n";
$status = mail($to, $subject, $message, $header);
if($status)
{
echo '<p>Your mail has been sent!</p>';
} else {
echo '<p>Something went wrong. Please try again!</p>';
}
respondido 08 nov., 19:12
26
- Siempre intente enviar encabezados en la función de correo.
- Si está enviando correo a través de localhost, realice la configuración de SMTP para enviar correo.
- Si está enviando correo a través de un servidor, verifique que la función de envío de correo electrónico esté habilitada en su servidor.
respondido 08 nov., 19:12
22
Si está usando una configuración SMTP para enviar su correo electrónico, intente usar PHPMailer en lugar de. Puedes descargar la biblioteca desde https://github.com/PHPMailer/PHPMailer.
Creé mi correo electrónico enviando de esta manera:
function send_mail($email, $recipient_name, $message='')
{
require("phpmailer/class.phpmailer.php");
$mail = new PHPMailer();
$mail->CharSet = "utf-8";
$mail->IsSMTP(); // Set mailer to use SMTP
$mail->Host = "mail.example.com"; // Specify main and backup server
$mail->SMTPAuth = true; // Turn on SMTP authentication
$mail->Username = "myusername"; // SMTP username
$mail->Password = "p@ssw0rd"; // SMTP password
$mail->From = "me@walalang.com";
$mail->FromName = "System-Ad";
$mail->AddAddress($email, $recipient_name);
$mail->WordWrap = 50; // Set word wrap to 50 characters
$mail->IsHTML(true); // Set email format to HTML (true) or plain text (false)
$mail->Subject = "This is a Sampleenter code here Email";
$mail->Body = $message;
$mail->AltBody = "This is the body in plain text for non-HTML mail clients";
$mail->AddEmbeddedImage('images/logo.png', 'logo', 'logo.png');
$mail->addAttachment('files/file.xlsx');
if(!$mail->Send())
{
echo "Message could not be sent. <p>";
echo "Mailer Error: " . $mail->ErrorInfo;
exit;
}
echo "Message has been sent";
}
respondido 08 nov., 19:11
También tuve que usar: require("phpmailer/class.smtp.php"); - Doug
18
Simplemente agregue algunos encabezados antes de enviar el correo:
<?php
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = 'contact@yoursite.com';
$subject = 'Customer Inquiry';
$body = "From: $name\n E-Mail: $email\n Message:\n $message";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html\r\n";
$headers .= 'From: from@example.com' . "\r\n" .
'Reply-To: reply@example.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
Y una cosa más. El mail()
La función no funciona en localhost. Sube tu código a un servidor y prueba.
Respondido el 12 de enero de 17 a las 21:01
esto realmente hizo que el formulario se enviara. Mi pregunta ahora sería... ¿cómo muestro el correo electrónico escrito por el usuario, ahora que lo reemplacé con el encabezado...? user3818620
¿Evitará el correo de la carpeta de correo no deseado? He visto si enviamos correo a más de 10 usando este método que usaste en tu código de gmail para enviar este correo a spam. - joyahuq
El OP tiene esta línea: $from = 'From: yoursite.com';
Lo que no parece una dirección de correo electrónico válida completa, no hay una parte local. Reemplazó el encabezado Desde y agregó otros adicionales. O más bien el $from
arriba es redundante en su ejemplo. Y estar mal formado fue probablemente el problema original de los OP. - Progrock
15
Funcionó para mí en 000webhost haciendo lo siguiente:
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type: text/html; charset=iso-8859-1" . "\r\n";
$headers .= "From: ". $from. "\r\n";
$headers .= "Reply-To: ". $from. "\r\n";
$headers .= "X-Mailer: PHP/" . phpversion();
$headers .= "X-Priority: 1" . "\r\n";
Introduzca directamente la dirección de correo electrónico al enviar el correo electrónico:
mail('email@gmail.com', $subject, $message, $headers)
Utilice la herramienta ''
y no ""
.
Este código funciona, pero el correo electrónico se recibió con media hora de retraso.
respondido 08 nov., 19:12
11
Sobre todo el mail()
La función está deshabilitada en el alojamiento compartido. Una mejor opción es usar SMTP. La mejor opción sería Gmail o SendGrid.
SMTPconfig.php
<?php
$SmtpServer="smtp.*.*";
$SmtpPort="2525"; //default
$SmtpUser="***";
$SmtpPass="***";
?>
SMTPmail.php
<?php
class SMTPClient
{
function SMTPClient ($SmtpServer, $SmtpPort, $SmtpUser, $SmtpPass, $from, $to, $subject, $body)
{
$this->SmtpServer = $SmtpServer;
$this->SmtpUser = base64_encode ($SmtpUser);
$this->SmtpPass = base64_encode ($SmtpPass);
$this->from = $from;
$this->to = $to;
$this->subject = $subject;
$this->body = $body;
if ($SmtpPort == "")
{
$this->PortSMTP = 25;
}
else
{
$this->PortSMTP = $SmtpPort;
}
}
function SendMail ()
{
$newLine = "\r\n";
$headers = "MIME-Version: 1.0" . $newLine;
$headers .= "Content-type: text/html; charset=iso-8859-1" . $newLine;
if ($SMTPIN = fsockopen ($this->SmtpServer, $this->PortSMTP))
{
fputs ($SMTPIN, "EHLO ".$HTTP_HOST."\r\n");
$talk["hello"] = fgets ( $SMTPIN, 1024 );
fputs($SMTPIN, "auth login\r\n");
$talk["res"]=fgets($SMTPIN,1024);
fputs($SMTPIN, $this->SmtpUser."\r\n");
$talk["user"]=fgets($SMTPIN,1024);
fputs($SMTPIN, $this->SmtpPass."\r\n");
$talk["pass"]=fgets($SMTPIN,256);
fputs ($SMTPIN, "MAIL FROM: <".$this->from.">\r\n");
$talk["From"] = fgets ( $SMTPIN, 1024 );
fputs ($SMTPIN, "RCPT TO: <".$this->to.">\r\n");
$talk["To"] = fgets ($SMTPIN, 1024);
fputs($SMTPIN, "DATA\r\n");
$talk["data"]=fgets( $SMTPIN,1024 );
fputs($SMTPIN, "To: <".$this->to.">\r\nFrom: <".$this->from.">\r\n".$headers."\n\nSubject:".$this->subject."\r\n\r\n\r\n".$this->body."\r\n.\r\n");
$talk["send"]=fgets($SMTPIN,256);
//CLOSE CONNECTION AND EXIT ...
fputs ($SMTPIN, "QUIT\r\n");
fclose($SMTPIN);
//
}
return $talk;
}
}
?>
contacto_email.php
<?php
include('SMTPconfig.php');
include('SMTPmail.php');
if($_SERVER["REQUEST_METHOD"] == "POST")
{
$to = "";
$from = $_POST['email'];
$subject = "Enquiry";
$body = $_POST['name'].'</br>'.$_POST['companyName'].'</br>'.$_POST['tel'].'</br>'.'<hr />'.$_POST['message'];
$SMTPMail = new SMTPClient ($SmtpServer, $SmtpPort, $SmtpUser, $SmtpPass, $from, $to, $subject, $body);
$SMTPChat = $SMTPMail->SendMail();
}
?>
Respondido el 13 de enero de 17 a las 04:01
¿Es una buena idea guardar el usuario y la contraseña smtp en texto sin formato en el servidor? - Juri
@Juri probablemente no... Dios, no puedo entender cómo hacer que funcione la función de correo :.( - user2230470
10
Si solo usas el mail()
función, debe completar el archivo de configuración.
Debe abrir la expansión de correo y configurar el SMTP smtp_port
y así sucesivamente, y lo más importante, su nombre de usuario y su contraseña. Sin eso, el correo no se puede enviar. Además, puede utilizar el PHPMail
clase a enviar.
respondido 08 nov., 19:11
10
Pruebe estas dos cosas por separado y juntas:
- eliminar el
if($_POST['submit']){}
- remove
$from
(solo mi instinto)
respondido 08 nov., 19:12
9
Creo que esto debería hacer el truco. Acabo de agregar un if(isset
y agregó concatenación a las variables en el cuerpo para separar PHP de HTML.
<?php
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = 'contact@yoursite.com';
$subject = 'Customer Inquiry';
$body = "From:" .$name."\r\n E-Mail:" .$email."\r\n Message:\r\n" .$message;
if (isset($_POST['submit']))
{
if (mail ($to, $subject, $body, $from))
{
echo '<p>Your message has been sent!</p>';
}
else
{
echo '<p>Something went wrong, go back and try again!</p>';
}
}
?>
Respondido el 12 de enero de 17 a las 22:01
9
Para cualquiera que encuentre esto en el futuro, no recomendaría usar mail
. Hay algunas respuestas que tocan esto, pero no el el porqué de la misma.
PHP mail
La función no solo es opaca, sino que depende completamente de lo que sea. MTA usas (es decir Sendmail) para hacer el trabajo. mail
seguirá , solamente decirle si el MTA no pudo aceptarlo (es decir, Sendmail estaba inactivo cuando intentó enviar). No puede decirle si el correo fue exitoso porque lo entregó. Como tal como La respuesta de Juan Conde detalles), ahora puede jugar con los registros del MTA y esperar que le diga lo suficiente sobre la falla para solucionarlo. Si está en un host compartido o no tiene acceso a los registros de MTA, no tiene suerte. Lamentablemente, el valor predeterminado para la mayoría de las instalaciones de Vanilla para Linux lo maneja de esta manera.
Una biblioteca de correo (PHPMailer, Zend Framework 2+, etc.), hace algo muy diferente a mail
. Abren un socket directamente al servidor de correo receptor y luego envían los comandos de correo SMTP directamente a través de ese socket. En otras palabras, la clase actúa como su propio MTA (tenga en cuenta que puede decirle a las bibliotecas que usen mail
para finalmente enviar el correo, pero le recomiendo encarecidamente que no lo haga).
Esto significa que puede ver directamente las respuestas del servidor receptor (en PHPMailer, por ejemplo, puede activar la salida de depuración). No más adivinanzas si un correo no se envió o por qué.
Si está utilizando SMTP (es decir, está llamando
isSMTP()
), puede obtener una transcripción detallada de la conversación SMTP utilizando elSMTPDebug
propiedad.Configure esta opción incluyendo una línea como esta en su secuencia de comandos:
$mail->SMTPDebug = 2;
También obtiene el beneficio de una mejor interfaz. Con mail
tiene que configurar todos sus encabezados, archivos adjuntos, etc. Con una biblioteca, tiene una función dedicada para hacer eso. También significa que la función está haciendo todas las partes difíciles (como los encabezados).
Respondido el 20 de junio de 20 a las 10:06
7
$name = $_POST['name'];
$email = $_POST['email'];
$reciver = '/* Reciver Email address */';
if (filter_var($reciver, FILTER_VALIDATE_EMAIL)) {
$subject = $name;
// To send HTML mail, the Content-type header must be set.
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .= 'From:' . $email. "\r\n"; // Sender's Email
//$headers .= 'Cc:' . $email. "\r\n"; // Carbon copy to Sender
$template = '<div style="padding:50px; color:white;">Hello ,<br/>'
. '<br/><br/>'
. 'Name:' .$name.'<br/>'
. 'Email:' .$email.'<br/>'
. '<br/>'
. '</div>';
$sendmessage = "<div style=\"background-color:#7E7E7E; color:white;\">" . $template . "</div>";
// Message lines should not exceed 70 characters (PHP rule), so wrap it.
$sendmessage = wordwrap($sendmessage, 70);
// Send mail by PHP Mail Function.
mail($reciver, $subject, $sendmessage, $headers);
echo "Your Query has been received, We will contact you soon.";
} else {
echo "<span>* invalid email *</span>";
}
Respondido 13 Jul 15, 08:07
7
Puede usar el correo electrónico de configuración por CodeIgniter. Por ejemplo, usando SMTP (manera simple):
$config = Array(
'protocol' => 'smtp',
'smtp_host' => 'mail.domain.com', // Your SMTP host
'smtp_port' => 26, // Default port for SMTP
'smtp_user' => 'name@domain.com',
'smtp_pass' => 'password',
'mailtype' => 'html',
'charset' => 'iso-8859-1',
'wordwrap' => TRUE
);
$message = 'Your msg';
$this->load->library('email', $config);
$this->email->from('name@domain.com', 'Title');
$this->email->to('emaildestination@domain.com');
$this->email->subject('Header');
$this->email->message($message);
if($this->email->send())
{
// Conditional true
}
¡Esto funciona para mi!
respondido 08 nov., 19:11
fsockopen() [function.fsockopen]: php_network_getaddresses: getaddrinfo falló: no se conoce tal host. - Si encuentro este error, ¿cuál es el motivo y qué se debe hacer? - Choudhury Saadmaan Mahmid
"Funciona para mí" es solo información anecdótica, pero en realidad no es una gran explicación. La contraseña de puerto y smtp sería engañosa para la mayoría de los usuarios. - Mario
Que es "correo electrónico de configuración"? Tiene una referencia? - Pedro Mortensen
5
Prueba esta
if ($_POST['submit']) {
$success= mail($to, $subject, $body, $from);
if($success)
{
echo '
<p>Your message has been sent!</p>
';
} else {
echo '
<p>Something went wrong, go back and try again!</p>
';
}
}
Respondido el 23 de junio de 15 a las 12:06
5
Quizás el problema sea la configuración del servidor de correo. Para evitar este tipo de problemas o que no tengas que preocuparte por el problema del servidor de correo, te recomiendo que utilices PHPMailer.
Es un plugin que tiene todo lo necesario para enviar correo, y lo único que tienes que tener en cuenta es tener habilitado el puerto SMTP (Puerto: 25 y 465).
require_once 'PHPMailer/PHPMailer.php';
require_once '/servicios/PHPMailer/SMTP.php';
require_once '/servicios/PHPMailer/Exception.php';
$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
try {
//Server settings
$mail->SMTPDebug = 0;
$mail->isSMTP();
$mail->Host = 'smtp.gmail.com';
$mail->SMTPAuth = true;
$mail->Username = 'correo@gmail.com';
$mail->Password = 'contrasenia';
$mail->SMTPSecure = 'ssl';
$mail->Port = 465;
// Recipients
$mail->setFrom('correo@gmail.com', 'my name');
$mail->addAddress('destination@correo.com');
// Attachments
$mail->addAttachment('optional file'); // Add files, is optional
// Content
$mail->isHTML(true);// Set email format to HTML
$mail->Subject = utf8_decode("subject");
$mail->Body = utf8_decode("mail content");
$mail->AltBody = '';
$mail->send();
}
catch (Exception $e) {
$error = $mail->ErrorInfo;
}
respondido 08 nov., 19:13
IANA reemplazó el puerto 465 por el puerto 587. Este es el puerto de envío de correo predeterminado. Cuando un cliente de correo electrónico o un servidor saliente envía un correo electrónico para que lo enrute un servidor de correo adecuado, siempre debe usar el puerto SMTP 587 como puerto predeterminado. Ver mailgun.com/blog/which-smtp-port-understanding-ports-25-465-587. Un sabio consejo: ¡No abra puertos en su computadora si no es completamente consciente de lo que está haciendo! - Daño
4
En primer lugar, es posible que tenga demasiados parámetros para la función mail()... Puede tener un máximo de cinco, mail(to, subject, message, headers, parameters);
En cuanto a la $from
variable va, eso debería provenir automáticamente de su servidor web si está usando Linux cPanel. Viene automáticamente de su nombre de usuario y dirección IP de cPanel.
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = 'contact@yoursite.com';
$subject = 'Customer Inquiry';
$body = "From: $name\n E-Mail: $email\n Message:\n $message";
También asegúrese de tener el orden correcto de las variables en su función mail().
La mail($to, $subject, $message, etc.)
en ese orden, o de lo contrario existe la posibilidad de que no funcione.
respondido 08 nov., 19:12
3
Asegúrese de tener Sendmail instalado en su servidor.
Si revisó su código y verificó que no hay nada malo allí, vaya a /var/mail y verifique si esa carpeta está vacía.
Si está vacío, deberá hacer lo siguiente:
sudo apt-get install sendmail
si está en un servidor Ubuntu.
Respondido el 24 de Septiembre de 17 a las 04:09
Eso es demasiado grueso para ser útil. La mera instalación de un MTA rara vez permitirá acceder a él. Y una guía completa de configuración de sendmail/postfix/qmail estaría fuera de tema aquí. - Mario
¿Este comentario se refiere a mi respuesta? Porque esto no me ha pasado y no lo resolví de la misma manera. Hay varias respuestas posibles a la pregunta, siendo la mía una de ellas después de haber intentado todo lo anterior en el pasado, mi respuesta me resolvió el problema, así que la ofrezco aquí como otra posible solución. - Daniel
Si seguro. Es una de las muchas respuestas posibles. Sin embargo, todavía es demasiado superficial en mi opinión. Sin embargo, generalizarlo en "necesita un MTA" como... - y aquí hay algunas guías de configuración vinculadas... podría ser más práctico. - Mario
3
Si tiene problemas para enviar correos con PHP, considere una alternativa como PHPMailer or SwiftMailer.
Usualmente uso SwiftMailer cuando necesito enviar correos con PHP.
Uso básico:
require 'mail/swift_required.php';
$message = Swift_Message::newInstance()
// The subject of your email
->setSubject('Jane Doe sends you a message')
// The from address(es)
->setFrom(array('jane.doe@gmail.com' => 'Jane Doe'))
// The to address(es)
->setTo(array('frank.stevens@gmail.com' => 'Frank Stevens'))
// Here, you put the content of your email
->setBody('<h3>New message</h3><p>Here goes the rest of my message</p>', 'text/html');
if (Swift_Mailer::newInstance(Swift_MailTransport::newInstance())->send($message)) {
echo json_encode([
"status" => "OK",
"message" => 'Your message has been sent!'
], JSON_PRETTY_PRINT);
} else {
echo json_encode([
"status" => "error",
"message" => 'Oops! Something went wrong!'
], JSON_PRETTY_PRINT);
}
Ver la documentación oficial para obtener más información sobre cómo usar SwiftMailer.
Respondido el 20 de junio de 20 a las 10:06
3
Para aquellos que no quieren usar correos externos y quieren enviar correo() en un servidor Linux dedicado.
La forma en que PHP envía correos se describe en php.ini
en la sección [mail function]
.
Parámetro sendmail-path
describe cómo se llama a sendmail. El valor predeterminado es sendmail -t -i
, así que si obtienes un trabajo sendmail -t -i < message.txt
en la consola de Linux, habrá terminado. También podrías agregar mail.log
para depurar y asegurarse de que mail() realmente se llame.
Diferentes MTA pueden implementar sendmail
. Simplemente hacen un enlace simbólico a sus binarios en ese nombre. por ejemplo, en Debian el valor predeterminado es Sufijo. Configura tu MTA para enviar correo y pruébalo desde la consola con sendmail -v -t -i < message.txt
. Archivo message.txt
debe contener todos los encabezados de un mensaje y un cuerpo, la dirección de destino del sobre se tomará del To:
encabezamiento. Ejemplo:
From: myapp@example.com
To: mymail@example.com
Subject: Test mail via sendmail.
Text body.
Prefiero usar ssmtp como MTA porque es simple y no requiere ejecutar un demonio con puertos abiertos. ssmtp se ajusta solo para enviar correo desde localhost. También puede enviar correo electrónico autenticado a través de su cuenta en un servicio de correo público. Instale ssmtp y edite el archivo de configuración /etc/ssmtp/ssmtp.conf
. Para poder recibir también correo del sistema local a cuentas Unix (alertas a root desde trabajos cron, por ejemplo) configure /etc/ssmtp/revaliases
archivo.
Aquí está mi configuración para mi cuenta en el correo de Yandex:
root=mymail@example.com
mailhub=smtp.yandex.ru:465
FromLineOverride=YES
UseTLS=YES
AuthUser=abcde@yandex.ru
AuthPass=password
respondido 08 nov., 19:13
2
Esto solo afectará a un pequeño puñado de usuarios, pero me gustaría documentarlo para ese pequeño puñado. Este miembro de ese pequeño grupo pasó 6 horas resolviendo un script de correo PHP que funcionaba debido a este problema.
Si vas a una universidad que ejecuta XAMPP desde www.AceITLab.com, debes saber lo que nuestro profesor no nos dijo: el firewall AceITLab (no el firewall de Windows) bloquea MercuryMail en XAMPP. Tendrás que usar un cliente de correo alternativo, pear está trabajando para nosotros. Deberá enviar a una cuenta de Gmail con configuraciones de seguridad bajas.
Sí, lo sé, esto es totalmente inútil para el correo electrónico del mundo real. Sin embargo, por lo que he visto, los entornos académicos y el mundo real a menudo tienen muy poco en común.
Respondido 05 Abr '17, 02:04
Eso es demasiado extrañamente específico y, de hecho, no ayudará a nadie más. Use el enlace [eliminar] debajo de su respuesta, por favor. - Mario
¿Qué es "pera" en este contexto? Quieres decir PERA, el repositorio de software PHP? ¿O algo mas? P.ej pares? - Pedro Mortensen
Realmente quieres decir "Precioso pequeño"? ¿Es algo que desear? ¿Por qué? - Pedro Mortensen
2
Sendmail ¡La instalación de Debian 10.0.0 ('Buster') fue de hecho trivial!
php.ini
[mail function]
sendmail_path=/usr/sbin/sendmail -t -i
; (Other directives are mostly windows)
Estándar sendmail instalación del paquete (permitiendo 'enviar'):
su - # Install as user 'root'
dpkg --list # Is install necessary?
apt-get install sendmail sendmail-cf m4 # Note multiple package selection
sendmailconfig # Respond all 'Y' for new install
Varios comandos útiles:
which sendmail # /usr/sbin/sendmail
which sendmailconfig # /usr/sbin/sendmailconfig
man sendmail # Documentation
systemctl restart sendmail # As and when required
Verificación (de la capacidad de enviar)
echo "Subject: sendmail test" | sendmail -v <yourEmail>@gmail.com
Lo anterior tomó alrededor de 5 minutos. Luego perdí 5 horas... No olvides revisar tu carpeta de spam!
respondido 08 nov., 19:13
1
Si está ejecutando este código en un servidor local (es decir, su computadora con fines de desarrollo), no enviará el correo electrónico al destinatario. Creará un .txt
archivo en una carpeta llamada mailoutput
.
En el caso de que esté utilizando un servicio de alojamiento gratuito, como 000webhost
or hostinger
, esos proveedores de servicios deshabilitan el mail()
función para evitar usos no deseados de suplantación de identidad por correo electrónico, spam, etc. Prefiero que se comunique con ellos para ver si admiten esta función.
Si está seguro de que el proveedor de servicios admite la función mail(), puede consultar este manual de PHP para obtener más referencias.
Para verificar si su servicio de alojamiento admite la función de correo (), intente ejecutar este código (recuerde cambiar la dirección de correo electrónico del destinatario):
<?php
$to = 'nobody@example.com';
$subject = 'the subject';
$message = 'hello';
$headers = 'From: webmaster@example.com' . "\r\n" .
'Reply-To: webmaster@example.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
?>
respondido 08 nov., 19:12
1
Puede utilizar el PHPMailer
y funciona perfectamente, aquí hay un ejemplo de código:
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'vendor/phpmailer/phpmailer/src/Exception.php';
require 'vendor/phpmailer/phpmailer/src/PHPMailer.php';
require 'vendor/phpmailer/phpmailer/src/SMTP.php';
$editor = $_POST["editor"];
$subject = $_POST["subject"];
$to = $_POST["to"];
try {
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$mail = new PHPMailer();
$mail->IsSMTP();
$mail->Mailer = "smtp";
$mail->SMTPDebug = 1;
$mail->SMTPAuth = TRUE;
$mail->SMTPSecure = "tls";
$mail->Port = 587;
$mail->Host = "smtp.gmail.com";//using smtp server
$mail->Username = "XXXXXXXXXX@gmail.com";//the email which will send the email
$mail->Password = "XXXXXXXXXX";//the password
$mail->IsHTML(true);
$mail->AddAddress($to, "recipient-name");
$mail->SetFrom("XXXXXXXXXX@gmail.com", "from-name");
$mail->AddReplyTo("XXXXXXXXXX@gmail.com", "reply-to-name");
$mail->Subject = $subject;
$mail->MsgHTML($editor);
if (!$mail->Send()) {
echo "Error while sending Email.";
var_dump($mail);
} else {
echo "Email sent successfully";
}
}
} catch (Exception $e) {
echo $e->getMessage();
}
Respondido el 27 de Septiembre de 21 a las 21:09
0
Hay varias posibilidades:
Está enfrentando un problema con el servidor. El servidor no tiene ningún servidor de correo. Entonces, su correo no funciona, porque su código está bien y el correo funciona con el tipo.
No está obteniendo el valor publicado. Pruebe su código con un valor estático.
Usar correos SMTP para enviar correo...
respondido 08 nov., 19:12
0
Puedes ver tus errores por:
error_reporting(E_ALL);
Y mi código de muestra es:
<?php
use PHPMailer\PHPMailer\PHPMailer;
require 'PHPMailer.php';
require 'SMTP.php';
require 'Exception.php';
$name = $_POST['name'];
$mailid = $_POST['mail'];
$mail = new PHPMailer;
$mail->IsSMTP();
$mail->SMTPDebug = 0; // Set mailer to use SMTP
$mail->Host = 'smtp.gmail.com'; // Specify main and backup server
$mail->Port = 587; // Set the SMTP port
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'someone@gmail.com'; // SMTP username
$mail->Password = 'password'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable encryption, 'ssl' also accepted
$mail->From = 'someone@gmail.com';
$mail->FromName = 'name';
$mail->AddAddress($mailid, $name); // Name is optional
$mail->IsHTML(true); // Set email format to HTML
$mail->Subject = 'Here is the subject';
$mail->Body = 'Here is your message' ;
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
if (!$mail->Send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
exit;
}
echo 'Message has been sent';
?>
respondido 08 nov., 19:13
SMTPDebug = 0
no es útil Tampoco funcionaría una simple "contraseña" con GMail. Esta respuesta no contribuye mucho aquí. - Mario
0
Si está atascado con una aplicación alojada en Hostgator, este es lo que resolvió mi problema. Muchas gracias al tipo que publicó la solución detallada. Por si algún día el enlace se desconecta, ahí tenéis el resumen:
- Busque la ruta de envío de correo electrónico en su servidor. Una forma sencilla de verificarlo es escribir temporalmente el siguiente código en una página a la que solo usted accederá, para leer la información generada:
<?php phpinfo(); ?>
. Abre esta página y buscasendmail path
. (¡Entonces, no olvides eliminar este código!) - Problema y solución: si su ruta de envío de correo dice solo
-t -i
, luego edite su servidorphp.ini
y agrega la siguiente línea:sendmail_path = /usr/sbin/sendmail -t -i;
Pero, después de poder enviar correos con PHP mail()
función, me enteré de que envía un correo electrónico no autenticado, lo que creó otro problema. Todos los correos electrónicos caían en el buzón de correo no deseado de mi Hotmail, y algunos correos electrónicos nunca se entregaron, lo que supongo que está relacionado con el hecho de que no están autenticados. Por eso decidí cambiar de mail()
a PHPMailer
con SMTP, después de todo.
Respondido 16 ago 20, 02:08
0
Puede ser un problema con "De:" $dirección de correo electrónico en esta parte de los $encabezados:
From: \"$name\" <$email>
Para probarlo, envíe un correo electrónico sin la parte de los encabezados, como:
mail('user@example.com', $subject, $message);
Si ese es el caso, intente usar una cuenta de correo electrónico que ya esté creada en el sistema desde el que está tratando de enviar correo.
Respondido el 12 de enero de 21 a las 14:01
0
<?php
$to = 'name@example.com';
$subject = 'Write your email subject here.';
$message = '
<html>
<head>
<title>Title here</title>
</head>
<body>
<p>Message here</p>
</body>
</html>
';
// Carriage return type (RFC).
$eol = "\r\n";
$headers = "Reply-To: Name <name@example.com>".$eol;
$headers .= "Return-Path: Name <name@example.com>".$eol;
$headers .= "From: Name <name@example.com>".$eol;
$headers .= "Organization: Hostinger".$eol;
$headers .= "MIME-Version: 1.0".$eol;
$headers .= "Content-type: text/html; charset=iso-8859-1".$eol;
$headers .= "X-Priority: 3".$eol;
$headers .= "X-Mailer: PHP".phpversion().$eol;
mail($to, $subject, $message, $headers);
Envío de correo electrónico HTML Al enviar un mensaje de correo electrónico, puede especificar una versión de Mime, un tipo de contenido y un conjunto de caracteres para enviar un correo electrónico HTML.
Ejemplo El ejemplo anterior enviará un mensaje de correo electrónico HTML a name@example.com. Puede codificar este programa de tal manera que reciba todo el contenido del usuario y luego envíe un correo electrónico.
Respondido 02 Jul 21, 02:07
Agregar el código no siempre es suficiente. Explique qué hace cada parte del código y por qué o por qué no funciona. Por favor lee, stackoverflow.com/help/how-to-answer - Syed Mohammad Sannan
0
Lo que resolvió este problema para mí fue que algunos proveedores no permiten destinatarios externos cuando usan el correo php:
Cambie el destinatario ($recipiente) en el código a un destinatario local. Esto significa utilizar una dirección de correo electrónico del dominio del servidor, por ejemplo, si el dominio de su servidor es www.yourdomain.com entonces el correo electrónico del destinatario debe ser alguien@tudominio.com. Cargue el archivo php modificado y vuelva a intentarlo. Si aún no funciona: cambia el remitente ($sender) a un correo electrónico local (usa el mismo correo electrónico que usaste para el destinatario). Cargue el archivo php modificado y vuelva a intentarlo.
¡Espero que esto ayude a algunos! https://www.arclab.com/en/kb/php/how-to-test-and-fix-php-mail-function.html
Respondido 18 Oct 21, 03:10
Parece fascinante que esta pregunta esté recibiendo respuestas incluso ahora. - Syed Mohammad Sannan
7 años 3 meses!! Raspé las pilas durante horas tratando de averiguar por qué algunos de mis formularios no se enviaban. Con suerte, la próxima persona en mi bote verá el código antiguo y dirá ¡ajá! - mondousage
Jajaja espero :) - Syed Mohammad Sannan
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas php html email or haz tu propia pregunta.
¿Está su programa en una computadora local o en un host en vivo? Tamil Selvan C
1. ¿estás seguro de que no va a tu correo no deseado? 2. ¿Tienes sendmail configurado en tu caja? - Steven Moseley
está en un host en vivo, no va a mi spam ... no estoy seguro de lo que quiere decir con tener sendmail configurado en mi casilla, así que supongo que no. - user3818620
intenta enviar sin
$from
- Artem IlchenkoMe encontré con un problema similar antes, y no fue causado por ninguno de los errores enumerados en la respuesta recomendada a continuación. Es porque mis listas de DNS una alternativa, servidor como el servidor de correo autorizado, pero el propio servidor web está configurado para reconocerse a sí mismo como el servidor de correo autorizado también. Así que cuando PHP
mail()
envía correos electrónicos a su propio dominio, no verifica los registros DNS para encontrar el servidor de correo correcto y simplemente se reenvía el correo electrónico a sí mismo. He escrito un artículo al respecto que detalla la solución: blog.terresquall.com/2021/04/… - John Doe