A função de correio PHP não conclui o envio de email

477
<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];
    $from = 'From: yoursite.com';
    $to = '[email protected]';
    $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>';
        }
    }
?>

Eu tentei criar um formulário de correio simples. O formulário em si está na minha index.htmlpágina, mas ele é enviado para uma página separada "obrigado pelo envio" thankyou.php, onde o código PHP acima está incorporado. O código é enviado perfeitamente, mas nunca envia um email. Como posso consertar isso?

user3818620
fonte
2
é o seu programa no computador local ou hospedeiro vivo
Tamil Selvan C
6
1. você tem certeza de que não está entrando no seu spam? 2. você tem o sendmail configurado em sua caixa?
Steven Moseley
está em um host ao vivo, não está entrando no meu spam ... não sei o que você quer dizer com ter o sendmail configurado na minha caixa, então suponho que não?
user3818620
tente enviar sem$from
Artem Ilchenko

Respostas:

512

Embora existam partes desta resposta que se aplicam apenas ao uso domail() própria função, muitas dessas etapas de solução de problemas podem ser aplicadas a qualquer sistema de correspondência PHP.

Há vários motivos pelos quais seu script parece não estar enviando e-mails. É difícil diagnosticar essas coisas, a menos que haja um erro de sintaxe óbvio. Sem um, você precisa percorrer a lista de verificação abaixo para encontrar possíveis armadilhas que possa estar encontrando.

Verifique se o relatório de erros está ativado e definido para relatar todos os erros

O relatório de erros é essencial para eliminar erros no seu código e erros gerais encontrados pelo PHP. O relatório de erros precisa estar ativado para receber esses erros. Colocar o seguinte código na parte superior dos arquivos PHP (ou em um arquivo de configuração principal) permitirá o relatório de erros.

error_reporting(-1);
ini_set('display_errors', 'On');
set_error_handler("var_dump");

Consulte Como posso obter mensagens de erro úteis em PHP? - esta resposta para mais detalhes sobre isso.

Verifique se a mail()função é chamada

Pode parecer bobagem, mas um erro comum é esquecer de realmente colocar o mail() função no seu código. Verifique se ele está lá e não comentou.

Verifique se a mail()função foi chamada corretamente

bool mail (string $ to, string $ subject, string $ message [, string $ additional_headers [, string $ additional_parameters]])

A função mail usa três parâmetros obrigatórios e, opcionalmente, um quarto e quinto. Se a sua chamada para mail()não tiver pelo menos três parâmetros, ela falhará.

Se a sua chamada para mail()não tiver os parâmetros corretos na ordem correta, também falhará.

Verifique os logs de correio do servidor

Seu servidor da web deve estar registrando todas as tentativas de enviar e-mails através dele. A localização desses logs variará (talvez seja necessário perguntar ao administrador do servidor onde eles estão localizados), mas eles geralmente podem ser encontrados no diretório raiz do usuário em logs. Dentro, haverá mensagens de erro que o servidor relatou, se houver, relacionadas às suas tentativas de enviar e-mails.

Verifique se há falha na conexão da porta

O bloco de portas é um problema muito comum que a maioria dos desenvolvedores enfrenta ao integrar seu código para entregar emails usando SMTP. E isso pode ser facilmente rastreado nos registros de servidor (a localização do servidor de log de correio pode variar de servidor para servidor, conforme explicado acima). Caso você esteja em um servidor de hospedagem compartilhado, as portas 25 e 587 permanecem bloqueadas por padrão. Este bloqueio foi feito propositadamente pelo seu provedor de hospedagem. Isso é verdade mesmo para alguns servidores dedicados. Quando essas portas estiverem bloqueadas, tente conectar-se usando a porta 2525. Se você achar que essa porta também está bloqueada, a única solução é entrar em contato com o provedor de hospedagem para desbloquear essas portas.

A maioria dos provedores de hospedagem bloqueia essas portas de email para proteger sua rede de enviar emails de spam.

Use as portas 25 ou 587 para conexões simples / TLS e a porta 465 para conexões SSL. Para a maioria dos usuários, é recomendável usar a porta 587 para evitar limites de taxa definidos por alguns provedores de hospedagem.

Não use o operador de supressão de erro

Quando o operador de supressão de erro @ é anexado a uma expressão em PHP, qualquer mensagem de erro que possa ser gerada por essa expressão será ignorada. Há circunstâncias em que o uso desse operador é necessário, mas o envio de correio não é um deles.

Se o seu código contiver @mail(...), você poderá ocultar mensagens de erro importantes que ajudarão você a depurar isso. Remova o @e veja se há algum erro relatado.

Só é aconselhável quando você verificarerror_get_last() imediatamente se há falhas concretas.

Verifica a mail() valor de retorno

A mail()função:

Retorna TRUEse o email foi aceito com êxito para entrega, FALSEcaso contrário. É importante observar que, apenas porque o correio foi aceito para entrega, isso NÃO significa que o correio realmente chegará ao destino pretendido.

Isso é importante notar porque:

  • Se você receber um FALSEvalor de retorno, sabe que o erro está no seu servidor aceitar seu e-mail. Provavelmente não é um problema de codificação, mas um problema de configuração do servidor. Você precisa falar com o administrador do sistema para descobrir por que isso está acontecendo.
  • Se você receber um TRUEvalor de retorno, isso não significa que seu email será definitivamente enviado. Significa apenas que o email foi enviado para o respectivo manipulador no servidor com sucesso pelo PHP. Ainda existem mais pontos de falha fora do controle do PHP que podem fazer com que o email não seja enviado.

Isso FALSEajudará a direcioná-lo na direção certa, enquanto TRUEisso não significa necessariamente que seu email foi enviado com sucesso. Isto é importante para anotar!

Verifique se o seu provedor de hospedagem permite enviar e-mails e não limita o envio de e-mails

Muitos webhosts compartilhados, especialmente provedores de hospedagem gratuitos, não permitem o envio de emails de seus servidores ou limitam o valor que pode ser enviado durante um determinado período de tempo. Isso se deve aos seus esforços para limitar os spammers a tirar proveito de seus serviços mais baratos.

Se você acha que seu host tem limites de email ou bloqueia o envio de emails, consulte as perguntas frequentes para ver se eles listam essas limitações. Caso contrário, pode ser necessário entrar em contato com o suporte deles para verificar se há alguma restrição em relação ao envio de emails.

Verifique pastas de spam; impedir que os e-mails sejam sinalizados como spam

Muitas vezes, por vários motivos, os e-mails enviados por PHP (e outras linguagens de programação do servidor) acabam na pasta de spam do destinatário. Sempre verifique lá antes de solucionar o seu código.

Para evitar que as mensagens enviadas pelo PHP sejam enviadas para a pasta de spam de um destinatário, há várias coisas que você pode fazer, tanto no seu código PHP quanto de outra forma, para minimizar as chances de seus e-mails serem marcados como spam. Boas dicas de Michiel de Mare incluem:

  • Use métodos de autenticação de e-mail, como SPF e DKIM, para provar que seus e-mails e seu nome de domínio estão juntos e para impedir a falsificação de seu nome de domínio. O site do SPF inclui um assistente para gerar as informações de DNS do seu site.
  • Verifique seu DNS reverso para garantir que o endereço IP do servidor de email aponte para o nome de domínio usado para o envio de email.
  • Verifique se o endereço IP que você está usando não está em uma lista negra
  • Verifique se o endereço de resposta é um endereço existente válido.
  • Use o nome completo e real do destinatário no campo Para, não apenas o endereço de e-mail (por exemplo "John Smith" <[email protected]>).
  • Monitore suas contas de abuso, como [email protected] e [email protected]. Isso significa - verifique se essas contas existem, leia o que é enviado a elas e atue nas reclamações.
  • Por fim, torná-lo muito fácil cancelar a inscrição. Caso contrário, seus usuários cancelarão a inscrição pressionando o botão de spam , o que afetará sua reputação.

Consulte Como garantir que o email enviado programaticamente não seja automaticamente marcado como spam? para saber mais sobre esse assunto.

Verifique se todos os cabeçalhos de email são fornecidos

Alguns softwares de spam rejeitarão os e-mails se houver cabeçalhos comuns ausentes, como "De" e "Responder para":

$headers = array("From: [email protected]",
    "Reply-To: [email protected]",
    "X-Mailer: PHP/" . PHP_VERSION
);
$headers = implode("\r\n", $headers);
mail($to, $subject, $message, $headers);

Verifique se os cabeçalhos de email não têm erros de sintaxe

Cabeçalhos inválidos são tão ruins quanto não ter cabeçalhos. Um caractere incorreto pode ser o suficiente para atrapalhar seu e-mail. Verifique duas vezes para garantir que sua sintaxe esteja correta, pois o PHP não detectará esses erros para você.

$headers = array("From [email protected]", // missing colon
    "Reply To: [email protected]",      // missing hyphen
    "X-Mailer: "PHP"/" . PHP_VERSION      // bad quotes
);

Não use um From:remetente falso

Embora o email deva ter um remetente De:, você não pode apenas usar qualquer valor. Em particular, endereços de remetente fornecidos pelo usuário são uma maneira infalível de bloquear emails:

$headers = array("From: $_POST[contactform_sender_email]"); // No!

Motivo: seu servidor da Web ou de envio de email não está na lista de permissões do SPF / DKIM para fingir ser responsável pelos endereços @hotmail ou @gmail. Pode até soltar e-mails silenciosamente com From:domínios de remetente para os quais não está configurado.

Verifique se o valor do destinatário está correto

Às vezes, o problema é tão simples quanto ter um valor incorreto para o destinatário do email. Isso pode ser devido ao uso de uma variável incorreta.

$to = '[email protected]';
// other variables ....
mail($recipient, $subject, $message, $headers); // $recipient should be $to

Outra maneira de testar isso é codificar o valor do destinatário na mail()chamada de função:

mail('[email protected]', $subject, $message, $headers); 

Isso pode se aplicar a todos os mail()parâmetros.

Enviar para várias contas

Para ajudar a excluir problemas de conta de email, envie seu email para várias contas de email em diferentes provedores de email . Se seus e-mails não chegarem à conta do Gmail de um usuário, envie os mesmos para uma conta do Yahoo, uma conta do Hotmail e uma conta POP3 comum (como a sua conta de e-mail fornecida pelo ISP).

Se os e-mails chegarem a todas ou algumas das outras contas de e-mail, você sabe que seu código está enviando e-mails, mas é provável que o provedor da conta de e-mail os esteja bloqueando por algum motivo. Se o email não chegar a nenhuma conta, é mais provável que o problema esteja relacionado ao seu código.

Verifique se o código corresponde ao método do formulário

Se você definiu o método do formulário POST, verifique se está usando os $_POSTvalores do formulário. Se você definiu GETou não definiu, verifique se você está usando os $_GETvalores do formulário.

Verifique se o actionvalor do formulário aponta para o local correto

Verifique se o actionatributo do formulário contém um valor que aponte para o seu código de correspondência PHP.

<form action="send_email.php" method="POST">

Verifique se o host da Web suporta o envio de email

Alguns provedores de hospedagem na Web não permitem ou ativam o envio de emails por meio de seus servidores. Os motivos para isso podem variar, mas se eles tiverem desativado o envio de e-mail, você precisará usar um método alternativo que usa terceiros para enviar esses e-mails para você.

Um email para o suporte técnico (após uma visita ao suporte on-line ou às Perguntas frequentes) deve esclarecer se os recursos de email estão disponíveis no seu servidor.

Verifique se o localhostservidor de email está configurado

Se você estiver desenvolvendo em sua estação de trabalho local usando WAMP, MAMP ou XAMPP, um servidor de email provavelmente não está instalado em sua estação de trabalho. Sem um, o PHP não pode enviar email por padrão.

Você pode superar isso instalando um servidor de email básico. Para Windows, você pode usar o Mercury Mail gratuito .

Você também pode usar o SMTP para enviar seus e-mails. Veja esta ótima resposta de Vikas Dwivedi para aprender como fazer isso.

Ativar o costume do PHP mail.log

Além do arquivo de log do MTA e do PHP, você pode habilitar o log para a mail()função especificamente. Ele não registra a interação SMTP completa, mas pelo menos parâmetros de chamada de função e script de chamada.

ini_set("mail.log", "/tmp/mail.log");
ini_set("mail.add_x_header", TRUE);

Veja http://php.net/manual/en/mail.configuration.php para obter detalhes. (É melhor ativar essas opções no php.iniou .user.iniou .htaccesstalvez.)

Verifique com um serviço de teste de correio

Existem vários serviços de entrega e verificação de spam que você pode utilizar para testar a configuração do MTA / servidor da web. Normalmente, você envia um endereço de e-mail para: seu endereço e, em seguida, obtém um relatório de entrega e mais análises ou falhas concretas posteriormente:

Use um mailer diferente

A mail()função incorporada do PHP é útil e geralmente faz o trabalho, mas tem suas deficiências . Felizmente, existem alternativas que oferecem mais poder e flexibilidade, incluindo o tratamento de muitos dos problemas descritos acima:

Tudo isso pode ser combinado com um servidor / provedor de serviços SMTP profissional. (Como os planos de hospedagem compartilhada típicos de 08/15 são bem-sucedidos quando se trata de instalação / configurabilidade de e-mail).

John Conde
fonte
11
Bem escrito, John. Gostaria de acrescentar mais uma coisa: a verificação dos logs do servidor de envio (se é hospedado local ou remotamente), se possível, geralmente pode esclarecer o que está causando o problema. Esses logs devem mostrar 1) se a mensagem foi ou não recebida do script PHP pelo servidor de envio e se sim, 2) se o MX receptor aceitou ou não a entrega do servidor de envio.
mti2935
@ mti2935 Isso é tão útil que estou surpreso por ter perdido isso. Certificarei de adicioná-lo em breve. :)
John Conde
1
Gostaria de começar com o uso não faça mail(), ele faz um trabalho tão pobre e é mais difícil de debug do que qualquer outra biblioteca de correio
1
o mesmo site no 000webhost envia e-mails com sucesso e rápido no domínio netai.net, mas no site88.net eu tenho o mesmo site no console que a mensagem é enviada com sucesso, mas não recebo nenhuma mensagem. Também no domínio comuf.com eu recebo erro (o mesmo site no mesmo host funciona somente no domínio netai.net, net16.net funciona também).
Nicolas Papaconstantinou
1
minha pergunta ( stackoverflow.com/questions/44866673/… ) foi marcada como duplicada, mas ainda não consigo descobrir. Alguma sugestão?
Zachary Elkins
37

Adicione um cabeçalho de correio na função de correio:

$header = "From: [email protected]\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>';
}
er.irfankhan11
fonte
25
  1. Sempre tente enviar cabeçalhos na função de email.
  2. Se você estiver enviando email pelo host local, faça as configurações de SMTP para enviar email.
  3. Se você estiver enviando email por um servidor, verifique se o recurso de envio de email está ativado no seu servidor.
sonam gupta
fonte
20

Se você estiver usando uma configuração SMTP para enviar seu email, tente usar o PHPMailer . Você pode baixar a biblioteca em https://github.com/PHPMailer/PHPMailer .

Criei meu email enviando assim:

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 = "[email protected]";
    $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";
}
oneDerer
fonte
2
Eu também tive que usar: require ("phpmailer / class.smtp.php");
Doug
15

Basta adicionar alguns cabeçalhos antes de enviar e-mails:

<?php 
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com'; 
$to = '[email protected]'; 
$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: [email protected]' . "\r\n" .
'Reply-To: [email protected]' . "\r\n" .
'X-Mailer: PHP/' . phpversion();

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

E mais uma coisa. A mail()função não está funcionando no host local. Faça o upload do seu código para um servidor e tente.

user1258544
fonte
1
isso realmente fez a forma submit-- minha questão agora seria be..how posso mostrar o usuário digitou no e-mail, agora que eu substituí-lo com o cabeçalho ...
user3818620
impedirá o correio da pasta de spam. Vi se enviamos e-mails com mais de 10 usando esse método que você usou no seu código. O gmail envia esse e-mail para spam.
jewelhuq
O OP tem esta linha: $from = 'From: yoursite.com'; que não parece um endereço de email válido completo, não há parte local. Você substituiu o cabeçalho De e adicionou outros. Ou melhor, o $fromacima é redundante no seu exemplo. E estar mal formado provavelmente era o problema original dos OPs.
Progrock
13

Funcionou para mim no 000webhost, fazendo o seguinte:

$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";

Digite diretamente o endereço de email ao enviar o email:

mail('[email protected]', $subject, $message, $headers)

Use ''e não"" .

Esse código funciona, mas o email foi recebido com meia hora de atraso.

bat .t
fonte
10

Principalmente a mail()função está desabilitada na hospedagem compartilhada. Uma opção melhor é usar o SMTP. A melhor opção seria o Gmail ou 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;
    } 
}
?>

contact_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();
}
?>
Karthik
fonte
É uma boa idéia salvar o usuário e a senha smtp em texto sem formatação no servidor?
Juri
@Juri provavelmente não ... Deus, eu não consigo descobrir como obter a função de e-mail para o trabalho:. (
9

Se você usar apenas a mail()função, precisará concluir o arquivo de configuração.

Você precisa abrir a expansão de email e definir o SMTP smtp_porte mais importante, seu nome de usuário e sua senha. Sem isso, o correio não pode ser enviado. Além disso, você pode usar a PHPMailclasse para enviar.

iatboy
fonte
9

Tente estas duas coisas separadamente e em conjunto:

  1. remova o if($_POST['submit']){}
  2. remover $from(apenas meu intestino)
vldfr
fonte
8

Eu acho que isso deve funcionar. Acabei de adicionar uma if(issetconcatenação e adicionei às variáveis ​​no corpo para separar o PHP do HTML.

<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];
    $from = 'From: yoursite.com'; 
    $to = '[email protected]'; 
    $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>'; 
    }
}

?>
Stephen M
fonte
8

Para quem acha isso daqui para frente, eu não recomendaria o uso mail. Há algumas respostas que tocam nisso, mas não o porquê disso.

A mailfunção do PHP não é apenas opaca, depende totalmente do MTA que você usa (por exemplo, Sendmail ) para fazer o trabalho. mailserá única dizer se o MTA não conseguiu aceitá-lo (ou seja, Sendmail foi para baixo quando você tentou enviar). Ele não pode dizer se o email foi bem-sucedido porque foi entregue. Como tal (como detalhes da resposta de John Conde ), agora você começa a mexer nos logs do MTA e espera que ele informe o suficiente sobre a falha para corrigi-lo. Se você estiver em um host compartilhado ou não tiver acesso aos logs do MTA, estará sem sorte. Infelizmente, o padrão para a maioria das instalações de baunilha para Linux lida com isso dessa maneira.

Uma biblioteca de correio ( PHPMailer , Zend Framework 2+, etc.) faz algo muito diferente mail. Eles abrem um soquete diretamente para o servidor de recebimento e enviam os comandos de email SMTP diretamente sobre esse soquete. Em outras palavras, a classe atua como seu próprio MTA (observe que você pode solicitar às bibliotecas que usem mailpara enviar o email, mas eu recomendo fortemente que você não faça isso).

Isso significa que você pode ver diretamente as respostas do servidor de recebimento (no PHPMailer, por exemplo, você pode ativar a saída de depuração ). Chega de adivinhar se um e-mail não foi enviado ou por quê.

Se você estiver usando SMTP (por exemplo, está ligando isSMTP()), poderá obter uma transcrição detalhada da conversa sobre SMTP usando a SMTPDebugpropriedade

Defina esta opção incluindo uma linha como esta em seu script:

$mail->SMTPDebug = 2;

Você também obtém o benefício de uma interface melhor. É mailnecessário configurar todos os cabeçalhos, anexos etc. Com uma biblioteca, você tem uma função dedicada para fazer isso. Isso também significa que a função está executando todas as partes complicadas (como cabeçalhos).

Machavity
fonte
6
$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>";
}
Chirag patel
fonte
6

Você pode usar o email de configuração pelo CodeIgniter . Por exemplo, usando SMTP (maneira simples):

$config = Array(
        'protocol' => 'smtp',
        'smtp_host' => 'mail.domain.com', // Your SMTP host
        'smtp_port' => 26, // Default port for SMTP
        'smtp_user' => '[email protected]',
        'smtp_pass' => 'password',
        'mailtype' => 'html',
        'charset' => 'iso-8859-1',
        'wordwrap' => TRUE
);
$message = 'Your msg';
$this->load->library('email', $config);
$this->email->from('[email protected]', 'Title');
$this->email->to('[email protected]');
$this->email->subject('Header');
$this->email->message($message);

if($this->email->send()) 
{
   // Conditional true
}

Funciona para mim!

dEsta88
fonte
1
fsockopen () [function.fsockopen]: php_network_getaddresses: getaddrinfo falhou: nenhum host é conhecido. - Se eu encontrar esse erro, qual é o motivo e o que precisa ser feito?
Choudhury Saadmaan Mahmid
1
"Funciona para mim" é apenas uma informação anedótica, mas na verdade não há muita explicação. A porta e a senha smtp seriam enganosas para a maioria dos usuários.
mario
O que é "email de configuração" ? Você tem uma referência?
Peter Mortensen
4

Tente isto

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>
        '; 
    }
}
Gaurav Sirauthiya
fonte
4

Talvez o problema seja a configuração do servidor de email. Para evitar esse tipo de problema ou você não precisa se preocupar com o problema do servidor de email, recomendo que você use o PHPMailer .

É um plug-in que tem todo o necessário para enviar e-mails, e a única coisa que você deve levar em consideração é ter a porta SMTP (portas: 25 e 465) ativada.

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 = '[email protected]';
    $mail->Password = 'contrasenia';
    $mail->SMTPSecure = 'ssl';
    $mail->Port = 465;

    // Recipients
    $mail->setFrom('[email protected]', 'my name');
    $mail->addAddress('[email protected]');

    // 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;
}
Jack Ch
fonte
1
A IANA substituiu a porta 465 pela porta 587. Essa é a porta de envio de email padrão. Quando um cliente de email ou servidor de saída está enviando um email para ser roteado por um servidor de email adequado, ele sempre deve usar a porta SMTP 587 como a porta padrão. Consulte mailgun.com/blog/which-smtp-port-understanding-ports-25-465-587 . Um conselho sensato: Não abra portas no seu computador se você não estiver completamente ciente do que está fazendo!
Dano
3

Verifique se o Sendmail está instalado no seu servidor.

Se você verificou seu código e verificou que não há nada errado, acesse / var / mail e verifique se essa pasta está vazia.

Se estiver vazio, você precisará fazer um:

sudo apt-get install sendmail

se você estiver em um servidor Ubuntu.

Daniel
fonte
Isso é muito grosseiro para ser útil. A simples instalação de um MTA raramente permite acessá-lo. E um guia de configuração completo do sendmail / postfix / qmail seria fora de tópico aqui.
mario
Este comentário faz referência à minha resposta? Porque isso não aconteceu comigo e eu não resolvi exatamente da mesma maneira. Existem várias respostas possíveis para a pergunta, sendo a minha uma delas depois de ter tentado todas as opções acima, minha resposta resolveu o problema para mim, então eu a ofereci aqui como outra solução potencial.
Daniel
Sim claro. É uma das muitas respostas possíveis. No entanto, ainda é caminho para a IMO superficial. Generalizando-o para "você precisa de um MTA", como ... - e aqui estão alguns guias de configuração vinculados ... pode ser mais prático.
Mario
3

Primeiro, você pode ter muitos parâmetros para a função mail () ... Você pode ter no máximo cinco, mail(to, subject, message, headers, parameters);

No que diz respeito à $fromvariável, isso deve vir automaticamente do seu host, se você estiver usando o Linux cPanel . Ele vem automaticamente do seu nome de usuário e endereço IP cPanel.

$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = '[email protected]';
$subject = 'Customer Inquiry';
$body = "From: $name\n E-Mail: $email\n Message:\n $message";

Verifique também se você tem a ordem correta das variáveis ​​na função mail ().

O mail($to, $subject, $message, etc.)nessa ordem, ou então há uma chance de não funcionar.

aidangig
fonte
3

Se você está tendo problemas para enviar e-mails com PHP, considere uma alternativa como PHPMailer ou SwiftMailer .

Eu normalmente uso o SwiftMailer sempre que preciso enviar e-mails com 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('[email protected]' => 'Jane Doe'))
    // The to address(es)
    ->setTo(array('[email protected]' => '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);
}

Consulte a documentação oficial para obter mais informações sobre como usar o SwiftMailer.

John Slegers
fonte
3

Para quem não deseja usar mala direta externa e deseja enviar mail () em um servidor Linux dedicado.

A maneira, como o PHP envia e-mails, é descrita php.inina seção[mail function] .

O parâmetro sendmail-pathdescreve como o sendmail é chamado. O valor padrão é sendmail -t -i, portanto, se você trabalhar sendmail -t -i < message.txtno console Linux - estará pronto. Você também pode adicionar mail.logao debug e garantir que mail () seja realmente chamado.

MTAs diferentes podem ser implementados sendmail. Eles apenas fazem um link simbólico para seus binários com esse nome. Por exemplo, no Debian, o padrão é Postfix . Configure seu MTA para enviar e-mail e testá-lo no console com sendmail -v -t -i < message.txt. O arquivo message.txtdeve conter todos os cabeçalhos de uma mensagem e um corpo; o endereço de destino do envelope será retirado do To:cabeçalho. Exemplo:

From: myapp@example.com
To: mymail@example.com
Subject: Test mail via sendmail.

Text body.

Prefiro usar ssmtp como MTA, porque é simples e não requer a execução de um daemon com portas abertas. O ssmtp se encaixa apenas no envio de email do host local . Ele também pode enviar email autenticado por meio da sua conta em um serviço de correio público. Instale o ssmtp e edite o arquivo de configuração /etc/ssmtp/ssmtp.conf. Para poder também receber correio do sistema local para contas Unix (alertas para raiz de tarefas cron, por exemplo), configure/etc/ssmtp/revaliases arquivo de .

Aqui está minha configuração para minha conta no e-mail Yandex:

root=mymail@example.com
mailhub=smtp.yandex.ru:465
FromLineOverride=YES
UseTLS=YES
AuthUser=abcde@yandex.ru
AuthPass=password
user3132194
fonte
2

Isso afetará apenas um pequeno grupo de usuários, mas eu gostaria que fosse documentado para esse pequeno grupo. Esse membro desse pequeno grupo passou 6 horas solucionando problemas de um script de correio PHP funcionando por causa desse problema.

Se você estiver indo para uma universidade que executa o XAMPP em www.AceITLab.com, deve saber o que nosso professor não nos disse: O firewall do AceITLab (não o firewall do Windows) bloqueia o MercuryMail no XAMPP. Você terá que usar um cliente de correio alternativo, a pear está trabalhando para nós. Você precisará enviar para uma conta do Gmail com configurações de baixa segurança.

Sim, eu sei, isso é totalmente inútil para emails do mundo real. No entanto, pelo que vi, as configurações acadêmicas e o mundo real geralmente têm muito pouco em comum.

TonyLuigiC
fonte
Isso é estranhamente específico e, de fato, ajudará mais ninguém. Use o link [excluir] abaixo da sua resposta, por favor.
mario
O que é "pêra" neste contexto? Você quer dizer PEAR , o repositório de software PHP? Ou alguma outra coisa? Por exemplo, pares ?
Peter Mortensen
Você realmente quer dizer "pouco precioso" ? É algo a desejar? Por quê?
Peter Mortensen
1

Se você estiver executando esse código em um servidor local (ou seja, seu computador para fins de desenvolvimento), ele não enviará o email ao destinatário. Ele criará um .txtarquivo em uma pasta chamadamailoutput .

No caso de você estar usando um serviço de mangueira gratuito, como 000webhostou hostinger, esses prestadores de serviços desativam a mail()função para impedir o uso não intencional de falsificação de e-mail, spam, etc.

Se você tem certeza de que o provedor de serviços suporta a função mail (), pode verificar este manual do PHP para obter mais referências,

Correio PHP ()

Para verificar se o serviço de hospedagem suporta a função mail (), tente executar este código (lembre-se de alterar o endereço de email do destinatário) :

<?php
    $to      = '[email protected]';
    $subject = 'the subject';
    $message = 'hello';
    $headers = 'From: [email protected]' . "\r\n" .
        'Reply-To: [email protected]' . "\r\n" .
        'X-Mailer: PHP/' . phpversion();

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

A instalação do Sendmail para o Debian 10.0.0 ('Buster') foi de fato trivial!

php.ini

[mail function]
sendmail_path=/usr/sbin/sendmail -t -i
; (Other directives are mostly windows)

Instalação padrão do pacote sendmail (permitindo '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

Comandos úteis diversos:

which sendmail                              # /usr/sbin/sendmail
which sendmailconfig                        # /usr/sbin/sendmailconfig
man sendmail                                # Documentation
systemctl restart sendmail                  # As and when required

Verificação (da capacidade de enviar)

echo "Subject: sendmail test" | sendmail -v <yourEmail>@gmail.com

O exposto acima levou cerca de 5 minutos. Então perdi 5 horas ... Não se esqueça de verificar sua pasta de spam !

Mau perdedor
fonte
0

Existem várias possibilidades:

  1. Você está enfrentando um problema no servidor. O servidor não possui nenhum servidor de correio. Portanto, seu e-mail não está funcionando, porque seu código está correto e o e-mail está funcionando com o tipo

  2. Você não está recebendo o valor lançado. Tente seu código com um valor estático.

  3. Use emails SMTP para enviar emails ...

SuReSh
fonte
0

Você pode usar o libmail: http://lwest.free.fr/doc/php/lib/index.php3?page=mail&lang=en

include "libmail.php";
$m = new Mail(); // Create the mail
$m->From($_POST['form']);
$m->To($_POST['to']);
$m->Subject($_POST['subject']);
$m->Body($_POST['body']);
$m->Cc($_POST['cc']);
$m->Priority(4);
// Attach a file of type 'image/gif' to be displayed in the message if possible
$m->Attach("/home/leo/toto.gif", "image/gif", "inline");
$m->Send(); // Send the mail
echo "Mail was sent:"
echo $m->Get(); // Show the mail source
Salim Ibrogimov
fonte
5
Importante mencionar: este é apenas um mail()wrapper de função. Adiciona apenas construção de mensagens e alguns truques.
mario
0

Você pode ver seus erros:

error_reporting(E_ALL);

E meu código de exemplo é:

<?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 = '[email protected]';  // SMTP username
    $mail->Password = 'password';           // SMTP password
    $mail->SMTPSecure = 'tls';              // Enable encryption, 'ssl' also accepted

    $mail->From = '[email protected]';
    $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';
?>
Krishna
fonte
1
SMTPDebug = 0não é útil. Nem uma "senha" simples funcionaria com o GMail. Esta resposta não contribui muito aqui.
mario
-2

Desde que seu sistema sendmail funcione, seu código deve ser modificado da seguinte maneira:

<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];

    $header ="
Content-Type: text/html; charset=UTF-8\r\n
MIME-Version: 1.0\r\n
From: \"$name\" <$email>\r\n
Reply-To: [email protected]\r\n
X-Mailer: yoursite.com mailer\r\n
";

    $to = '"Contact" <[email protected]>'; 
    $subject = 'Customer Inquiry';
    $body =<<<EOB
<!DOCTYPE html>
<html>
    <body>
        $message
    </body>
</html>
EOB;

    if ($_POST['submit']) {
        if (mail ($to, $subject, $body, $header) !== false) { 
            echo '<p>Your message has been sent!</p>';
        } else { 
            echo '<p>Something went wrong, go back and try again!</p>'; 
        }
    }
?>

Isso permite que você envie e-mails baseados em HTML.

De interesse notável:

  1. nós construímos uma sequência de multilinhas de cabeçalho (cada linha separada por \ r \ n);
  2. adicionamos Content-type para expressar que retornamos HTML para que você possa compor e-mails melhores (você pode adicionar o código HTML que você deseja, incluindo CSS, à sua mensagem, como faria na página HTML).

Nota: a <<<EOBsintaxe requer que o último marcador EOB comece como o início da linha e não tem espaço ou qualquer caractere após o ponto e vírgula.

Stéphane de Luca
fonte