使用PHPMailer

时间:2018-02-28 19:25:03

标签: php phpmailer

我在网站上有一个基本的联系表格。我需要将表单结果发送到2个电子邮件地址... 1)我,& 2)向提交表格的人确认。发送给提交者的表单结果中包含不同的消息。

我计划添加 jQuery验证& Ajax 但首先我想让PHP运行起来。所以我不认为我需要大量的PHP验证,只需要一个基本的 - 如果关键字段为空,则为错误信息,作为后备。

我正在使用PHPMailer但不幸的是他们的文档非常缺乏我缺乏PHP技能的人。但经过大量的谷歌搜索后,我已经能够拼凑出大部分可行的东西。这是我的代码使用一个小表单(稍后会有更多字段)

这会将表单发送到两个电子邮件地址 - 太棒了!

我遇到问题的部分是验证&错误/成功消息。

如果我只使用return $mail->send();部分末尾的function sendemail,则会发送正常的信息。但如果我尝试在字段中没有任何内容提交表单,则没有任何反应。所以我尝试添加我在某处找到的if(!$mail->send()) {...else...}件,它也适用于有效的表单信息,但如果没有,则不行。

所以,我应该用什么代替呢?或者它会不同于if / else部分的结尾?

<?php

if (isset($_POST['submit'])) {

    date_default_timezone_set('US/Central');

    require 'PHPMailer-5.2.26/PHPMailerAutoload.php';

    function sendemail(
            $SK_emailTo, 
            $SK_emailSubject, 
            $SK_emailBody
            ) {

        $mail = new PHPMailer;

        $mail->setFrom('myEmail@gmail.com', 'My Name');

        $mail->addReplyTo($_POST['email'], $_POST['name']);

        $mail->addAddress($SK_emailTo);
        $mail->Subject  = $SK_emailSubject;
        $mail->Body     = $SK_emailBody;
        $mail->isHTML(true);

        $mail->isSMTP();
        $mail->Host = 'smtp.gmail.com';
        $mail->SMTPAuth = true;
        $mail->SMTPSecure = 'tls';
        $mail->Port = 587;
        $mail->Username = 'myEmail@gmail.com';
        $mail->Password = 'myPwd';


        //return $mail->send(); //this works by itself, without IF/ELSE, but doesn't return error if empty form fields
        if(!$mail->send()) {
            return 'There is a problem' . $mail->ErrorInfo;
        }else{
            return 'ok'; // this works but i don't know why
        }

    } //end function sendemail

    // form fields to variables
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];

    // from function sendmail to ASSIGN VALUES to...
    /*      $SK_emailTo, 
            SK_emailSubject, 
            $SK_emailBody */
    if (sendemail(
            'myEmail@address.com', 
            'First email subject', 
            'Form results to me...
             <br><br>'.$message
        )) {

        sendemail(
            $email, 
            'Second email subject', 
            'Confirmation email to person who submitted the form... 
             <br><br>'.$message
        );

        $msg = 'Email sent!';
    } else {
        $msg = 'Email failed!' . $mail->ErrorInfo;
    }

} //end if submit
?>

作为旁注,为什么return 'ok';有效?什么是&#39; ok&#39;部分附加到?

谢谢!

<小时/> ////////////////////////编辑:新信息但尚未解决/////////////// /////////

基于建议&amp;下面由Mauro编辑(以及帖子中的评论),这是我现在所处的位置......

<?php
if (isset($_POST['submit'])) {

    date_default_timezone_set('US/Central');

    require 'PHPMailer-5.2.26/PHPMailerAutoload.php';

    function sendemail(
            $SK_emailTo, 
            $SK_emailSubject, 
            $SK_emailBody
            ) {

        $mail = new PHPMailer(true);

        $mail->setFrom('myEmail@gmail.com', 'My Name');

        $mail->addReplyTo($_POST['email'], $_POST['name']);

        $mail->addAddress($SK_emailTo);
        $mail->Subject  = $SK_emailSubject;
        $mail->Body     = $SK_emailBody;
        $mail->isHTML(true);

        $mail->isSMTP();
        $mail->Host = 'smtp.gmail.com';
        $mail->SMTPAuth = true;
        $mail->SMTPSecure = 'tls';
        $mail->Port = 587;
        $mail->Username = 'myEmail@gmail.com';
        $mail->Password = 'myPwd';

        return $mail->send();

    } //end function sendemail

    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];

    try {
        sendemail(
            'myEmail@address.com', 
            'First email subject', 
            'Form results to me...
             <br><br>'.$message
        );
        sendemail(
            $email, 
            'Second email subject', 
            'Confirmation email to person who submitted the form... 
             <br><br>'.$message
        );
        echo 'Email sent!';
    } //end try

    catch (phpmailerException $e) { //catches PHPMailer errors
        echo 'There is a problem; the message did NOT send. Please go back and check that you have filled in all the required fields and there are no typos in your email address.';
        echo $e->errorMessage();
    } 
    catch (Exception $e) { //catches validation errors
        echo 'There is a problem; the message did NOT send. Please either go back and try again or contact us at email@address.com';
        echo $e->getMessage();
    }

    function validateEmpty($string, $name = 'name') {
        $string = trim($string);
        if ($string == '') {
            throw new Exception(sprintf('%s is empty.', $name));
        }
    }

} //end if submit
?>

... STILL

1)Mauro建议我使用use error_log()记录错误消息。我怎么做?是什么产生了ftp目录中的错误消息的文本文件?

2)Mauro还建议使用an $error & $success flag。什么是&amp;我该怎么做?

3)如果&#34;名称&#34;我希望在上面catch中有自定义错误消息。 &amp; /或&#34;电子邮件&#34;字段(可能还有其他字段)只是空的。 Mauro编写了上面的function validateEmpty代码,但我无法使其工作。我是否在脚本中的错误位置或使用它做了其他错误?

3b)我认为这个功能只适用于&#34; name&#34;字段,我必须复制它为&#34;电子邮件&#34;场?

请记住...... 我希望能够在这里进行SIMPLE验证作为后备,以防Javascript / Jquery由于某种原因而无法正常工作。 还要注意上面的内容&#34;发送&#34;电子邮件正确;所以我现在只是想获得验证&amp;错误信息正常工作。

谢谢你的时间&amp;专业知识!

1 个答案:

答案 0 :(得分:1)

tl; dr:两个语句都评估为true。最好返回truefalse而不是字符串,然后再处理该消息。

首先我会处理你的问题,然后我会就良好做法提出一些建议。

当您在PHP和大多数语言中使用return x;时,您将“x”发送回您调用该函数的位置。因此,当您的代码执行时,它将被读作:

if('ok')

if ('Error info...')

PHP将if语句(这是括号之间的部分)的条件评估为truefalse,将其转换为the boolean type。 PHP中的字符串到布尔转换基本如下:any non-empty string evaluates as TRUE(按照链接,检查第一个表,最后一列)。

所以,如果成功,你的函数返回'ok','错误信息......'如果失败,这些都是非空字符串,并且评估为true,所以无论是第一个电子邮件发送尝试进展顺利,您的脚本将尝试发送第二个,并始终将$msg设置为“发送电子邮件!”。

以下是关于如何修复脚本以使其更好地工作(和外观)的一些建议:

  1. 正如@Matt所建议的那样,最好自己验证数据,而不是依靠PHPMailer这样做。尽管如果目标地址无效,PHPMailer将返回错误,但如果电子邮件无效,最好不要调用库。所以:

    • 首先,使用javascript验证数据,以便您的用户获得即时反馈。
    • 然后,使用PHP验证它(可能会创建一个新的validate()函数,可以使用filter_var()来验证电子邮件。
    • 最后,仅在前两个成功的情况下发送电子邮件。
  2. 要遵循您的思路,您应该评估sendemail()返回的字符串是否等于'ok':

    if (sendemail(...) == 'ok')
    

    但是,不是评估两个不同的字符串('ok'或'Error info ...'),如果函数返回布尔值而不是since PHPMailer's send() already does更好,只需保留它,就像你评论它一样:

    return $mail->send()
    
  3. 您的最后一行是使用$mail,这是您在函数中声明的变量,而您从未创建过global,因此在那时它将无法使用,因为您是尝试获取属性(ErrorInfo),您将触发两个PHP通知:Undefined variableTrying to get a property from a non-object。您可以在函数顶部添加global $mail,这将使其全局可用(在函数范围之外),但这被认为是一种不好的做法,因为在大量代码中您可能会感到困惑。

    相反,解决错误的一种更简洁的方法是抛出/捕捉exception

    function sendemail(...) {
    
        // ... PHPMailer config ...
    
        if ($mail->send()) {
            return true;
        } else {
            throw Exception('Error: ' + $mail->ErrorInfo);
        }
    }
    
    // later...
    try {
        sendemail()
        $msg = 'Email sent!';
    } catch (Exception $e) {
        $msg = 'Email failed!' . $e->getMessage();
    }
    

    此处,如果发送电子邮件时出现问题,您的函数将throw一般性异常,catch部分将被执行。

    更好

    如果你这样初始化PHPMailer:

    $mail = new PHPMailer(true); // note the parameter set to true.
    

    如果它无法发送电子邮件并且您将能够捕获异常,它将自行抛出异常:

    function sendemail(...) {
        $mail = PHPMailer(true); // this line
        // ... PHPMailer config ...
        return $mail->send(); // just to return something, we aren't really using this value anymore.
    }
    
    // later...
    try {
        sendemail(...)
        $msg = 'Email sent!';
    } catch (phpmailerException $e) {
        echo $e->errorMessage(); // Catch PHPMailer exceptions (email sending failure)
    } catch (Exception $e) {
        echo $e->getMessage(); // Boring error messages from anything else!
    }
    
  4. 永远不要忘记read the docs