PHP mail function doesn't complete sending of

2019-09-10 03:35发布

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

I've tried creating a simple mail form. The form itself is on my index.html page, but submits to a separate "thank you for your submission" page, thankyou.php, where the above PHP code is embedded. The code submits perfectly, but never sends an email. please help.

标签: php html email
27条回答
霸刀☆藐视天下
2楼-- · 2019-09-10 04:07

For anyone who finds this going forward, I would not recommend using mail. There's some answers that touch on this, but not the why of it.

PHP's mail function is not only opaque, it fully relies on whatever MTA you use (i.e. Sendmail) to do the work. mail will ONLY tell you if the MTA failed to accept it (i.e. Sendmail was down when you tried to send). It cannot tell you if the mail was successful because it's handed it off. As such (as John Conde's answer details), you now get to fiddle with the logs of the MTA and hope that it tells you enough about the failure to fix it. If you're on a shared host or don't have access to the MTA logs, you're out of luck. Sadly, the default for most vanilla installs for Linux handle it this way.

A mail library (PHPMailer, Zend Framework 2+, etc), does something very different from mail. What they do is they open a socket directly to the receiving mail server and then send the SMTP mail commands directly over that socket. In other words, the class acts as its own MTA (note that you can tell the libraries to use mail to ultimately send the mail, but I would strongly recommend you not do that).

What this means for you is that you can then directly see the responses from the receiving server (in PHPMailer, for instance, you can turn on debugging output). No more guessing if a mail failed to send or why.

If you're using SMTP (i.e. you're calling isSMTP()), you can get a detailed transcript of the SMTP conversation using the SMTPDebug property.

Set this option by including a line like this in your script:

$mail->SMTPDebug = 2;

You also get the benefit of a better interface. With mail you have to set up all your headers, attachments, etc. With a library, you have a dedicated function to do that. It also means the function is doing all the tricky parts (like headers).

查看更多
趁早两清
3楼-- · 2019-09-10 04:07

I think this should do the trick. I just added an if(isset and added concatenation to the variables in the body to separate PHP from 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>'; 
    }
}

?>
查看更多
迷人小祖宗
4楼-- · 2019-09-10 04:07

Provided your sendmail system works, your code must be modified as follows:

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

This enables you to send HTML-based emails.

Of notable interest:

  1. we built a header multilines string (each line separated by\r\n);
  2. we added Content-type to express we return HTML so that you can compose better emails (you can add nay HTML code you want, including CSS, to your message as you would do in HTML page).

Note: <<<EOB syntax requires the last EOB marker begins as the beginning pf the line and has no space or whatever character after the semicolon.

查看更多
小情绪 Triste *
5楼-- · 2019-09-10 04:09

Try this

<?php
$to = "somebody@example.com, somebodyelse@example.com";
$subject = "HTML email";

$message = "
    <html>
    <head>
       <title>HTML email</title>
    </head>
    <body>
      <p>This email contains HTML Tags!</p>
      <table>
        <tr>
         <th>Firstname</th>
         <th>Lastname</th>
        </tr>
        <tr>
          <td>John</td>
          <td>Doe</td>
        </tr>
      </table>
    </body>
    </html>";

// Always set content-type when sending HTML email
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";

// More headers
$headers .= 'From: <webmaster@example.com>' . "\r\n";
$headers .= 'Cc: myboss@example.com' . "\r\n";

mail($to,$subject,$message,$headers);
?> 
查看更多
家丑人穷心不美
6楼-- · 2019-09-10 04:09

For those who do not want to use external mailers and want to mail() on a dedicated linux server.

The way, how php mails, is described in php.ini in section [mail function]. Parameter sendmail-path describes how sendmail is called. Default value is sendmail -t -i, so if you get working sendmail -t -i < message.txt in linux console - you will be done. You could also add mail.log to debug and be sure mail() is really called.

Different MTA can implement sendmail, they just make symbolic link to their binaries on that name. For example, in debian default is postfix. Configure your MTA to send mail and test it from console with sendmail -v -t -i < message.txt. File message.txt should contain all headers of a message and a body, destination addres for envelope will be taken from To: header. Example:

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

Text body.

I prefere to use ssmtp as MTA because it is simple and do not require running daemon with opened ports. ssmtp fits only for sending mail from local host, it also can send authenticated email via your account on a public mail service. Install ssmtp and edit config /etc/ssmtp/ssmtp.conf. To be able also to recive local system mail to unix accounts(alerts to root from cron jobs, for example) configure /etc/ssmtp/revaliases file.

Here is my config for my account on Yandex mail:

root=mymail@example.com
mailhub=smtp.yandex.ru:465
FromLineOverride=YES
UseTLS=YES
AuthUser=abcde@yandex.ru
AuthPass=password
查看更多
Bombasti
7楼-- · 2019-09-10 04:10

are you using SMTP configuration for sending your email? try using phpmailer instead. you can download the library from https://github.com/PHPMailer/PHPMailer. i created my email sending this way:

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";
}
查看更多
登录 后发表回答