La funzione di posta PHP non completa l'invio di e-mail


477
<?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>';
        }
    }
?>

Ho provato a creare un semplice modulo di posta. Il modulo stesso è sulla mia index.htmlpagina, ma invia a una pagina separata "grazie per l'invio" thankyou.php, in cui è incorporato il codice PHP sopra riportato. Il codice si invia perfettamente, ma non invia mai un'e-mail. Come posso risolvere questo problema?


2
è il tuo programma nel computer locale o live host
Tamil Selvan C

6
1. sei sicuro che non stia andando nel tuo spam? 2. hai sendmail configurato sulla tua scatola?
Steven Moseley,

è su un host dal vivo non sta andando nel mio spam..non sono sicuro di cosa intendi con aver configurato sendmail sulla mia scatola quindi presumo di no?
user3818620

prova a inviare senza$from
Artem Ilchenko l'

Risposte:


512

Sebbene ci siano parti di questa risposta che si applicano solo all'utilizzo dimail() funzione stessa, molti di questi passaggi per la risoluzione dei problemi possono essere applicati a qualsiasi sistema di posta PHP.

Esistono diversi motivi per cui il tuo script sembra non inviare e-mail. È difficile diagnosticare queste cose a meno che non ci sia un evidente errore di sintassi. Senza uno è necessario scorrere l'elenco di controllo qui sotto per trovare eventuali insidie ​​che potresti incontrare.

Assicurarsi che la segnalazione errori sia abilitata e impostata per segnalare tutti gli errori

La segnalazione degli errori è essenziale per eliminare i bug nel codice e gli errori generali riscontrati da PHP. La ricezione degli errori deve essere abilitata per ricevere questi errori. Posizionare il seguente codice nella parte superiore dei file PHP (o in un file di configurazione principale) consentirà la segnalazione degli errori.

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

Vedi Come posso ottenere utili messaggi di errore in PHP? - questa risposta per maggiori dettagli al riguardo.

Assicurarsi che la mail()funzione sia chiamata

Può sembrare sciocco ma un errore comune è dimenticare di inserire effettivamente la mail()funzione nel codice. Assicurati che sia lì e non commentato.

Assicurarsi che la mail()funzione sia chiamata correttamente

bool mail (stringa $ a, stringa $ oggetto, stringa $ messaggio [, stringa $ additional_headers [, stringa $ additional_parameters]])

La funzione mail accetta tre parametri richiesti e, facoltativamente, un quarto e un quinto. Se la tua chiamata a mail()non ha almeno tre parametri fallirà.

Se la tua chiamata a mail()non ha i parametri corretti nell'ordine corretto, fallirà anche.

Controlla i log di posta del server

Il tuo server web dovrebbe registrare tutti i tentativi di invio di e-mail attraverso di esso. La posizione di questi registri varierà (potrebbe essere necessario chiedere all'amministratore del server dove si trovano) ma è possibile trovarli comunemente nella directory principale di un utente in logs. All'interno ci saranno messaggi di errore segnalati dal server, se presenti, relativi ai tuoi tentativi di invio di e-mail.

Verificare la connessione alla porta non riuscita

Il blocco delle porte è un problema molto comune che la maggior parte degli sviluppatori deve affrontare mentre integra il proprio codice per recapitare le e-mail tramite SMTP. E questo può essere facilmente rintracciato nei maillog del server (la posizione del server del registro di posta può variare da server a server, come spiegato sopra). Nel caso in cui ci si trovi su un server di hosting condiviso, le porte 25 e 587 rimangono bloccate per impostazione predefinita. Questo blocco è stato fatto di proposito dal tuo provider di hosting. Questo è vero anche per alcuni server dedicati. Quando queste porte sono bloccate, prova a connetterti utilizzando la porta 2525. Se trovi che anche quella porta è bloccata, l'unica soluzione è contattare il tuo provider di hosting per sbloccare queste porte.

La maggior parte dei provider di hosting blocca queste porte e-mail per proteggere la propria rete dall'invio di e-mail di spam.

Utilizzare le porte 25 o 587 per connessioni semplici / TLS e la porta 465 per connessioni SSL. Per la maggior parte degli utenti, si consiglia di utilizzare la porta 587 per evitare limiti di velocità stabiliti da alcuni provider di hosting.

Non utilizzare l'operatore di soppressione degli errori

Quando l' operatore di soppressione degli errori@ viene anteposto a un'espressione in PHP, tutti i messaggi di errore che potrebbero essere generati da tale espressione verranno ignorati. Ci sono circostanze in cui è necessario l'uso di questo operatore ma l'invio di posta non è uno di questi.

Se il tuo codice contiene, @mail(...)potresti nascondere importanti messaggi di errore che ti aiuteranno a eseguire il debug. Rimuovere il @e vedere se vengono segnalati errori.

È consigliabile solo quando si verificaerror_get_last() subito dopo la presenza di guasti concreti.

Controlla il mail()valore di ritorno

La mail()funzione:

Restituisce TRUEse la posta è stata accettata correttamente per la consegna, FALSEaltrimenti. È importante notare che solo perché la posta è stata accettata per la consegna, NON significa che la posta raggiungerà effettivamente la destinazione prevista.

Questo è importante notare perché:

  • Se ricevi un FALSEvalore di ritorno, sai che l'errore risiede nel fatto che il tuo server accetta la tua posta. Questo probabilmente non è un problema di codifica ma un problema di configurazione del server. Devi parlare con l'amministratore di sistema per scoprire perché ciò sta accadendo.
  • Se ricevi un TRUEvalore di ritorno, ciò non significa che la tua email verrà sicuramente inviata. Significa semplicemente che l'email è stata inviata con successo al rispettivo gestore sul server da PHP. Esistono ancora più punti di errore al di fuori del controllo di PHP che possono impedire l'invio dell'e-mail.

Quindi, FALSEvi aiuterà a puntare nella giusta direzione, mentre TRUEnon non necessariamente significa che il vostro email è stata inviata con successo. Questo è importante da notare!

Assicurati che il tuo provider di hosting ti consenta di inviare e-mail e non limiti l'invio di e-mail

Molti webhost condivisi, in particolare i provider di web hosting gratuiti, non consentono l'invio di e-mail dai loro server o limitano l'importo che può essere inviato durante un determinato periodo di tempo. Ciò è dovuto ai loro sforzi per impedire agli spammer di usufruire dei loro servizi più economici.

Se ritieni che il tuo host abbia limiti di email o blocchi l'invio di email, controlla le loro FAQ per vedere se elencano tali limitazioni. In caso contrario, potrebbe essere necessario contattare il loro supporto per verificare se esistono restrizioni in merito all'invio di e-mail.

Controlla le cartelle spam; impedire che le e-mail vengano contrassegnate come spam

Spesso, per vari motivi, le e-mail inviate tramite PHP (e altri linguaggi di programmazione lato server) finiscono nella cartella spam di un destinatario. Controlla sempre lì prima di risolvere il codice.

Per evitare che la posta inviata tramite PHP venga inviata alla cartella spam di un destinatario, ci sono varie cose che puoi fare, sia nel tuo codice PHP che in altro modo, per ridurre al minimo le possibilità che le tue e-mail vengano contrassegnate come spam. I buoni consigli di Michiel de Mare includono:

  • Utilizzare metodi di autenticazione e-mail, come SPF e DKIM per dimostrare che le e-mail e il nome del dominio appartengono insieme e per impedire lo spoofing del nome del dominio. Il sito Web SPF include una procedura guidata per generare le informazioni DNS per il tuo sito.
  • Controlla il tuo DNS inverso per assicurarti che l'indirizzo IP del tuo server di posta punti al nome di dominio che usi per inviare la posta.
  • Assicurati che l'indirizzo IP che stai utilizzando non sia su una lista nera
  • Assicurarsi che l'indirizzo di risposta sia un indirizzo valido ed esistente.
  • Utilizza il nome reale completo del destinatario nel campo A, non solo l'indirizzo e-mail (ad es "John Smith" <john@blacksmiths-international.com>.).
  • Monitora i tuoi account sugli abusi, come abuse@tuodominio.com e postmaster@tuodominio.com. Ciò significa: assicurati che questi account esistano, leggi cosa viene loro inviato e agisci in caso di reclami.
  • Infine, lo rendono davvero facile da annullare l'iscrizione. Altrimenti, i tuoi utenti annulleranno l'iscrizione premendo il pulsante spam e ciò influenzerà la tua reputazione.

Vedi Come assicurarti che le email che invii a livello di codice non vengano automaticamente contrassegnate come spam? per ulteriori informazioni su questo argomento.

Assicurati che siano fornite tutte le intestazioni della posta

Alcuni software di spam rifiuteranno la posta se mancano le intestazioni comuni come "Da" e "Rispondi 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);

Assicurarsi che le intestazioni della posta non presentino errori di sintassi

Le intestazioni non valide sono altrettanto dannose di non avere intestazioni. Un carattere errato potrebbe essere tutto ciò che serve per far deragliare la tua email. Ricontrolla per assicurarti che la sintassi sia corretta poiché PHP non rileverà questi errori per te.

$headers = array("From from@example.com", // missing colon
    "Reply To: replyto@example.com",      // missing hyphen
    "X-Mailer: "PHP"/" . PHP_VERSION      // bad quotes
);

Non usare un From:mittente falso

Mentre la posta deve avere un mittente From: non puoi semplicemente usare qualsiasi valore. In particolare, gli indirizzi mittente inviati dall'utente sono un modo infallibile per bloccare la posta:

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

Motivo: il tuo server di posta web o di invio non è autorizzato dalla SPF / DKIM a far finta di essere responsabile degli indirizzi @hotmail o @gmail. Potrebbe anche eliminare silenziosamente le e-mail con From:domini mittente per i quali non è configurato.

Assicurarsi che il valore del destinatario sia corretto

A volte il problema è semplice come avere un valore errato per il destinatario dell'e-mail. Ciò può essere dovuto all'uso di una variabile errata.

$to = 'user@example.com';
// other variables ....
mail($recipient, $subject, $message, $headers); // $recipient should be $to

Un altro modo per testarlo è codificare il valore del destinatario nella mail()chiamata di funzione:

mail('user@example.com', $subject, $message, $headers); 

Questo può applicarsi a tutti i mail()parametri.

Invia a più account

Per aiutare a escludere i problemi relativi agli account e-mail, invia la tua e-mail a più account e-mail presso diversi provider di posta elettronica . Se le tue e-mail non arrivano all'account Gmail di un utente, invia le stesse e-mail a un account Yahoo, un account Hotmail e un normale account POP3 (come il tuo account e-mail fornito dall'ISP).

Se le e-mail arrivano a tutti o ad alcuni degli altri account e-mail, sai che il tuo codice sta inviando e-mail, ma è probabile che il provider dell'account e-mail li stia bloccando per qualche motivo. Se l'e-mail non arriva a nessun account e-mail, è più probabile che il problema sia correlato al tuo codice.

Assicurarsi che il codice corrisponda al metodo del modulo

Se hai impostato il metodo del modulo su POST, assicurati di utilizzare $_POSTper cercare i valori del modulo. Se è stato impostato su GETo non è stato impostato affatto, assicurarsi di utilizzare $_GETper cercare i valori del modulo.

Assicurarsi che il actionvalore del modulo punti nella posizione corretta

Assicurati che l' actionattributo del modulo contenga un valore che punta al tuo codice postale PHP.

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

Assicurarsi che l'host Web supporti l'invio di e-mail

Alcuni provider di hosting Web non consentono o abilitano l'invio di e-mail attraverso i loro server. I motivi di ciò possono variare, ma se hanno disabilitato l'invio di posta sarà necessario utilizzare un metodo alternativo che utilizza una terza parte per inviare tali e-mail.

Un'e-mail al loro supporto tecnico (dopo un viaggio al loro supporto online o FAQ) dovrebbe chiarire se le funzionalità e-mail sono disponibili sul tuo server.

Assicurarsi che il localhostserver di posta sia configurato

Se stai sviluppando sulla tua workstation locale usando WAMP, MAMP o XAMPP, probabilmente sulla tua workstation non è installato un server di posta elettronica. Senza uno, PHP non può inviare la posta per impostazione predefinita.

È possibile superare questo installando un server di posta di base. Per Windows è possibile utilizzare la Mercury Mail gratuita .

Puoi anche utilizzare SMTP per inviare le tue e-mail. Guarda questa fantastica risposta di Vikas Dwivedi per imparare a farlo.

Abilita personalizzato di PHP mail.log

Oltre al file di registro di MTA e PHP, è possibile abilitare in modo specifico la registrazione per la mail()funzione . Non registra l'interazione SMTP completa, ma almeno i parametri di chiamata delle funzioni e lo script di invocazione.

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

Vedi http://php.net/manual/en/mail.configuration.php per i dettagli. (È meglio abilitare queste opzioni nel php.inio .user.inio .htaccessforse.)

Verificare con un servizio di test della posta

Esistono vari servizi di consegna e controllo dello spam che è possibile utilizzare per testare la configurazione del proprio MTA / server web. In genere si invia un probe di posta a: il loro indirizzo, quindi si ottiene un rapporto di consegna e ulteriori errori o analisi concrete in seguito:

Usa un altro mailer

La mail()funzione integrata di PHP è utile e spesso fa il lavoro ma ha i suoi difetti . Fortunatamente ci sono alternative che offrono maggiore potenza e flessibilità, inclusa la gestione di molti dei problemi sopra descritti:

Tutto ciò può essere combinato con un server SMTP / fornitore di servizi professionale. (Perché i tipici piani di webhosting 08/15 condivisi sono incerti o meno quando si tratta di impostazione / configurabilità della posta elettronica.)


11
Ben scritto, John. Vorrei solo aggiungere un'altra cosa: controllare i registri del server di posta del server di posta di invio (sia esso ospitato localmente o in remoto), se possibile, può spesso far luce su ciò che sta causando il problema. Questi registri dovrebbero mostrare 1) se il messaggio è stato ricevuto o meno dallo script PHP dal server di posta mittente e, in tal caso, 2) se il MX ricevente ha accettato o meno la consegna dal server di posta mittente.
mti2935,

@ mti2935 È così utile che sono sorpreso di averlo perso. Sarò sicuro di aggiungerlo a breve. :)
John Conde,

1
vorrei iniziare con non usare mail(), fa un lavoro così scarso ed è più difficile eseguire il debug di qualsiasi altra libreria di posta

1
lo stesso sito Web su 000webhost invia e-mail con successo e velocità sul dominio netai.net ma su site88.net ho lo stesso sito Web che ottengo nella console che il messaggio invia correttamente ma non ricevo alcun messaggio. Anche nel dominio comuf.com ricevo un errore (lo stesso sito Web sullo stesso host funziona solo sul dominio netai.net, funziona anche net16.net)
Nicolas Papaconstantinou,

1
la mia domanda ( stackoverflow.com/questions/44866673/… ) è stata contrassegnata come duplicata di questa, ma non riesco ancora a capirla. Eventuali suggerimenti?
Zachary Elkins,

37

Aggiungi un'intestazione di posta nella funzione di posta:

$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>';
}

25
  1. Prova sempre a inviare le intestazioni nella funzione posta.
  2. Se si sta inviando posta tramite localhost, eseguire le impostazioni SMTP per l'invio di posta.
  3. Se stai inviando posta attraverso un server, controlla che la funzione di invio email sia abilitata sul tuo server.

20

Se stai usando una configurazione SMTP per inviare la tua email, prova invece a usare PHPMailer . È possibile scaricare la libreria da https://github.com/PHPMailer/PHPMailer .

Ho creato la mia e-mail inviando in questo modo:

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

2
Ho anche dovuto usare: require ("phpmailer / class.smtp.php");
Doug,

15

Aggiungi solo alcune intestazioni prima di inviare la posta:

<?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);

E un'altra cosa. La mail()funzione non funziona in localhost. Carica il tuo codice su un server e prova.


1
questo in realtà ha fatto l'invio del modulo-- la mia domanda ora sarebbe..come faccio a mostrare l'e-mail digitata dall'utente, ora che l'ho sostituito con l'intestazione ...
user3818620

impedirà la posta dalla cartella spam. Ho visto se inviamo posta più di 10 usando questo metodo che hai usato nel tuo codice gmail invia questa posta allo spam.
Jewelhuq,

L'OP ha questa linea: $from = 'From: yoursite.com'; che non sembra un indirizzo e-mail valido completo, non esiste una parte locale. Hai sostituito l'intestazione Da e ne hai aggiunti altri. O meglio quanto $fromsopra è ridondante nel tuo esempio. Ed essere malformato era probabilmente il problema originale dei PO.
Progrock,

13

Ha funzionato per me su 000webhost nel modo seguente:

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

Inserisci direttamente l'indirizzo e-mail quando invii l'e-mail:

mail('email@gmail.com', $subject, $message, $headers)

Usa ''e non "".

Questo codice funziona, ma l'e-mail è stata ricevuta con un ritardo di mezz'ora.


10

Principalmente la mail()funzione è disabilitata nell'hosting condiviso. Un'opzione migliore è utilizzare SMTP. L'opzione migliore sarebbe 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;
    } 
}
?>

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();
}
?>

È una buona idea salvare l'utente smtp e la password in chiaro sul server?
Juri,

@Juri probabilmente no ... dio non riesco a capire come far funzionare la funzione mail:. (

9

Se si utilizza solo la mail()funzione, è necessario completare il file di configurazione.

È necessario aprire l'espansione della posta, impostare SMTP smtp_porte così via, e soprattutto, il nome utente e la password. Senza questo, la posta non può essere inviata. Inoltre, puoi utilizzare la PHPMailclasse per inviare.


9

Prova queste due cose separatamente e insieme:

  1. Rimuovi il if($_POST['submit']){}
  2. rimuovi $from(solo il mio istinto)

8

Penso che questo dovrebbe fare il trucco. Ho appena aggiunto if(issete aggiunto la concatenazione alle variabili nel corpo per separare PHP dall'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>'; 
    }
}

?>

8

Per chiunque lo trovi in ​​futuro, non consiglierei l'uso mail. Ci sono alcune risposte che toccano questo, ma non il perché .

La mailfunzione di PHP non è solo opaca, si basa completamente su qualsiasi MTA che usi (ad es. Sendmail ) per fare il lavoro. mailti dirà solo se l'MTA non lo ha accettato (ovvero Sendmail era inattivo quando hai provato a inviare). Non può dirti se la posta ha avuto successo perché è stata consegnata. Come tale (come la risposta di John Conde dettagli ), ora puoi armeggiare con i registri dell'MTA e sperare che ti dica abbastanza sull'incapacità di risolverlo. Se sei su un host condiviso o non hai accesso ai registri MTA, sei sfortunato. Purtroppo, l'impostazione predefinita per la maggior parte delle installazioni vanilla per Linux la gestisce in questo modo.

Una libreria di posta ( PHPMailer , Zend Framework 2+, ecc.) Fa qualcosa di molto diverso da mail. Aprono un socket direttamente al server di posta ricevente e quindi inviano i comandi di posta SMTP direttamente su quel socket. In altre parole, la classe agisce come un proprio MTA (nota che puoi dire alle librerie di usare mailper inviare infine la posta, ma ti consiglio vivamente di non farlo).

Ciò significa che puoi quindi vedere direttamente le risposte dal server ricevente (in PHPMailer, ad esempio, puoi attivare l'output di debug ). Non dovrai più indovinare se non è stato possibile inviare una mail o perché.

Se stai usando SMTP (cioè stai chiamando isSMTP()), puoi ottenere una trascrizione dettagliata della conversazione SMTP usando la SMTPDebugproprietà.

Imposta questa opzione includendo una linea come questa nel tuo script:

$mail->SMTPDebug = 2;

Ottieni anche il vantaggio di un'interfaccia migliore. Con mailè necessario impostare tutte le intestazioni, allegati, ecc Con una libreria, si dispone di una funzione dedicata per farlo. Significa anche che la funzione sta eseguendo tutte le parti difficili (come le intestazioni).


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

6

Puoi usare l'e-mail di configurazione di CodeIgniter . Ad esempio, utilizzando SMTP (modo semplice):

$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
}

Per me funziona!


1
fsockopen () [function.fsockopen]: php_network_getaddresses: getaddrinfo non riuscito: non è noto tale host. - Se riscontro questo errore, qual è la ragione e cosa bisogna fare?
Choudhury Saadmaan Mahmid,

1
"Funziona per me" è solo un'informazione aneddotica, ma in realtà non ha molte spiegazioni. La porta e la password smtp sarebbero fuorvianti per la maggior parte degli utenti.
mario

Che cos'è "config email" ? Hai un riferimento?
Peter Mortensen,

4

Prova questo

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>
        '; 
    }
}

4

Forse il problema è la configurazione del server di posta. Per evitare questo tipo di problemi o non devi preoccuparti del problema del server di posta, ti consiglio di usare PHPMailer .

È un plug-in che ha tutto il necessario per inviare la posta e l'unica cosa che devi prendere in considerazione è avere la porta SMTP (Porta: 25 e 465) abilitata.

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;
}

1
IANA ha sostituito la porta 465 con la porta 587. Questa è la porta di invio della posta predefinita. Quando un client di posta elettronica o un server in uscita sta inviando un'e-mail per essere indirizzata da un server di posta appropriato, dovrebbe sempre utilizzare la porta SMTP 587 come porta predefinita. Vedi mailgun.com/blog/which-smtp-port-understanding-ports-25-465-587 . Un saggio consiglio: non aprire le porte del computer se non si è completamente consapevoli di ciò che si sta facendo!
Danneggiamento del

3

Assicurati di avere Sendmail installato sul tuo server.

Se hai controllato il tuo codice e verificato che non c'è nulla di sbagliato lì, vai su / var / mail e controlla se quella cartella è vuota.

Se è vuoto, dovrai fare un:

sudo apt-get install sendmail

se sei su un server Ubuntu.


È troppo grossolano per essere utile. La semplice installazione di un MTA raramente consentirà di raggiungerlo. E una guida completa all'installazione di sendmail / postfix / qmail sarebbe fuori tema qui.
mario

Questo commento è in riferimento alla mia risposta? Perché questo non mi è successo e non l'ho risolto nello stesso modo esatto. Esistono varie possibili risposte alla domanda, la mia è una di queste dopo aver provato tutte le precedenti in passato, la mia risposta aveva risolto il problema per me, quindi l'ho offerto qui come un'altra potenziale soluzione.
Daniel,

Si certo. È una delle tante risposte possibili. Tuttavia, è ancora un modo per IMO superficiale. Generalizzarlo in "hai bisogno di un MTA" come ... - e qui ci sono alcune guide di installazione collegate ... potrebbe essere comunque più pratico.
mario,

3

Prima di tutto, potresti avere troppi parametri per la funzione mail () ... Puoi avere al massimo cinque, mail(to, subject, message, headers, parameters);

Per quanto riguarda la $fromvariabile, dovrebbe provenire automaticamente dal tuo host web se usi Linux cPanel . Viene automaticamente dal tuo nome utente e indirizzo IP 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";

Assicurati anche di avere l'ordine corretto delle variabili nella tua funzione mail ().

In mail($to, $subject, $message, etc.)questo ordine, oppure c'è la possibilità che non funzioni.


3

Se hai problemi a inviare e-mail con PHP, prendi in considerazione un'alternativa come PHPMailer o SwiftMailer .

Di solito uso SwiftMailer ogni volta che devo inviare e-mail con PHP.


Utilizzo di base:

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);
}

Consulta la documentazione ufficiale per ulteriori informazioni su come utilizzare SwiftMailer.


3

Per coloro che non vogliono usare mailer esterni e vogliono mail () su un server Linux dedicato.

Il modo in cui PHP spedisce è descritto php.ininella sezione[mail function] .

Il parametro sendmail-pathdescrive come viene chiamato sendmail. Il valore predefinito è sendmail -t -i, quindi se riesci a lavorare sendmail -t -i < message.txtnella console di Linux, avrai finito. Puoi anche aggiungere mail.logal debug ed essere sicuro che mail () sia davvero chiamato.

Possono essere implementati MTA diversi sendmail. Fanno solo un collegamento simbolico ai loro binari con quel nome. Ad esempio, in Debian il default è Postfix . Configura il tuo MTA per inviare posta e testarlo dalla console con sendmail -v -t -i < message.txt. Il file message.txtdeve contenere tutte le intestazioni di un messaggio e un corpo, l'indirizzo di destinazione per la busta verrà preso dall'intestazione To:. Esempio:

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

Text body.

Preferisco usare ssmtp come MTA perché è semplice e non richiede l'esecuzione di un demone con porte aperte. ssmtp è adatto solo per l'invio di posta da localhost . Può anche inviare e-mail autenticate tramite il tuo account su un servizio di posta pubblico. Installa ssmtp e modifica il file di configurazione /etc/ssmtp/ssmtp.conf. Per poter anche ricevere la posta di sistema locale agli account Unix (ad esempio avvisi di root da cron job) configurare il /etc/ssmtp/revaliasesfile.

Ecco la mia configurazione per il mio account sulla posta Yandex:

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

2

Questo interesserà solo una piccola manciata di utenti, ma mi piacerebbe documentarlo per quella piccola manciata. Questo membro di quella piccola manciata ha trascorso 6 ore a risolvere questo problema con uno script di posta PHP funzionante.

Se stai andando in un'università che gestisce XAMPP da www.AceITLab.com, dovresti sapere cosa non ci ha detto il nostro professore: il firewall AceITLab (non il firewall di Windows) blocca MercuryMail in XAMPP. Dovrai utilizzare un client di posta alternativo, pera sta lavorando per noi. Dovrai inviare a un account Gmail con impostazioni di sicurezza basse.

Sì, lo so, questo è totalmente inutile per l'email del mondo reale. Tuttavia, da quello che ho visto, le impostazioni accademiche e il mondo reale spesso hanno poco in comune.


È troppo stranamente specifico e non aiuterà davvero nessun altro. Usa il link [elimina] sotto la tua risposta per favore.
mario

Cosa è "pera" in questo contesto? Intendi PEAR , il repository di software PHP? O qualcos'altro? Ad esempio, tra pari ?
Peter Mortensen,

Intendi davvero "piccolo prezioso" ? È qualcosa da desiderare? Perché?
Peter Mortensen,

1

Se stai eseguendo questo codice su un server locale (cioè il tuo computer a scopi di sviluppo), non invierà l'e-mail al destinatario. Creerà un .txtfile in una cartella denominatamailoutput .

Nel caso in cui si stia utilizzando un servizio di hosing gratuito, come 000webhosto hostinger, tali provider di servizi disabilitano ilmail() funzione per prevenire usi involontari di spoofing e-mail, spamming, ecc. Preferisco che tu li contatti per vedere se supportano questa funzione.

Se sei sicuro che il fornitore di servizi supporti la funzione mail (), puoi consultare questo manuale di PHP per ulteriori riferimenti,

Posta PHP ()

Per verificare se il servizio di hosting supporta la funzione mail (), prova a eseguire questo codice (ricorda di cambiare l'indirizzo e-mail 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);
?>

1

L' installazione di Sendmail per Debian 10.0.0 ('Buster') era in effetti banale!

php.ini

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

Installazione standard del pacchetto sendmail (che consente 'invia'):

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

Comandi utili vari:

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

Verifica (della capacità di inviare)

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

Quanto sopra ha impiegato circa 5 minuti. Poi ho perso 5 ore ... Non dimenticare di controllare la tua cartella spam !


0

Esistono diverse possibilità:

  1. Stai affrontando un problema con il server. Il server non ha alcun server di posta. Quindi la tua posta non funziona, perché il tuo codice va bene e la posta funziona con il tipo.

  2. Non stai ottenendo il valore pubblicato. Prova il tuo codice con un valore statico.

  3. Usa mail SMTP per inviare mail ...


0

Puoi usare 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

5
Importante da menzionare: questo è semplicemente un mail()wrapper di funzioni. Aggiunge solo la costruzione del messaggio e alcuni espedienti.
mario

0

Puoi vedere i tuoi errori:

error_reporting(E_ALL);

E il mio codice di esempio è:

<?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';
?>

1
SMTPDebug = 0non è utile. Né una semplice "password" funzionerebbe con GMail. Questa risposta non contribuisce molto qui.
Mario,

-2

Se il tuo sistema sendmail funziona, il tuo codice deve essere modificato come segue:

<?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: no-reply@yoursite.com\r\n
X-Mailer: yoursite.com mailer\r\n
";

    $to = '"Contact" <contact@yoursite.com>'; 
    $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>'; 
        }
    }
?>

Ciò consente di inviare e-mail basate su HTML.

Di notevole interesse:

  1. abbiamo creato una stringa multilinea di intestazione (ogni riga separata da \ r \ n);
  2. abbiamo aggiunto il tipo di contenuto per esprimere che restituiamo HTML in modo da poter comporre e-mail migliori (puoi aggiungere al tuo messaggio un codice HTML che desideri, incluso CSS, come faresti nella pagina HTML).

Nota: la <<<EOBsintassi richiede che l'ultimo marcatore EOB inizi come inizio della riga e non abbia spazio o qualsiasi carattere dopo il punto e virgola.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.