【问题标题】:Form to Email PHP Validation fallback using PHPMailer使用 PHPMailer 发送电子邮件 PHP 验证回退
【发布时间】:2018-02-28 19:25:02
【问题描述】:

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

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

我正在使用 PHPMailer,但不幸的是,对于我缺乏 php 技能的人来说,他们的文档非常缺乏。但经过多次谷歌搜索,我已经能够拼凑出一些最有效的东西。这是我使用小表单的代码(稍后会出现更多字段)

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

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

如果我只是在function sendemail 部分的末尾使用return $mail->send();,它发送得很好。但是如果我尝试在字段中没有任何内容的情况下提交表单,则不会发生任何事情。所以我尝试添加我在某处找到的 if(!$mail->send()) {...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'; 有效? 'ok' 部分附加到什么上?

谢谢!


///////////////////// 编辑:新信息但仍未解决////////////// /////////

根据下面 Mauro 的建议和编辑(以及在那篇帖子中的 cmets),这就是我现在所处的位置......

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

还是……

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

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

3) 如果“姓名”和/或“电子邮件”字段(可能还有其他字段)为空,我想在上述catch 中显示自定义错误消息。 Mauro 写了上面的function validateEmpty 代码,但我无法让它工作。是我把它放在脚本中的错误位置还是做错了什么?

3b) 在我看来,此功能仅适用于“姓名”字段,我是否必须为“电子邮件”字段复制它?

请记住... 我希望能够在这里进行简单的验证作为后备,以防 Javascript/Jquery 由于某种原因无法正常工作。 另请注意,上述内容确实“发送”了电子邮件;所以我现在只是试图让验证和错误消息正常工作。

感谢您的时间和专业知识!

【问题讨论】:

  • 你的问题主题是你的旁注,我不确定你真正想从我们这里得到什么
  • 您的if 语句如下所示:如果邮件未发送,则返回一个表明存在问题的字符串,以及 errorInfo,否则返回一个显示“好的' - 但你问它为什么“有效”,这不清楚你的意思。它“有效”是因为邮件发送正确吗?注意:如果你的整个代码块不在函数中,那么return 什么都不做。我建议阅读 return 的作用。
  • @rtfm - 你是对的;我很抱歉。我想我的头脑有点混乱,不仅要理解部分代码,还要使其正常工作。我会更改标题和一些语言。
  • @cale_b - 我尝试阅读 php 并且由于某种原因它没有陷入困境。这种编程不是我的强项。我不认为在网站上制作简单的联系表格会如此复杂。我很惊讶我无法找到非常完整的教程/示例来复制/粘贴/修改。我将在下面对 Mauro 向我解释的内容进行拍摄。感谢您的意见。
  • 仅供参考:我从 youtube.com/watch?v=Mw_ORXPoogY 获得了原始代码 - 我确实在 github.com/PHPMailer/PHPMailer/blob/master/examples/… 看到了示例,但也没有理解。

标签: php phpmailer


【解决方案1】:

tl;dr:两个语句的计算结果都是true。最好返回truefalse而不是字符串,稍后再处理消息。

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

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

if('ok')

if ('Error info...')

PHP 通过将the boolean type 转换为truefalse 来评估if 语句(这是括号之间的部分)上的条件。 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,因此它在那时将不可用,因为您正在尝试获取一个属性(@ 987654352@) 你将触发两个 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!
    }
    

永远不要忘记read the docs

【讨论】:

  • 感谢您的时间和专业知识!但我仍然有一些问题;-) 我用你的“更好”部分修改了我的代码。可以看到@codeshare.io/5PzyZd - 并且 我在它的末尾添加了4个问题。我真的很感谢您(或其他人)在回答这 4 个问题时花费更多时间和知识。谢谢!!!
  • 我无法得到你提供的工作。我做了一些笔记和问题@codeshare.io/5z6R4O - 再次感谢你!!!
  • 嘿@Mauro - 仍然希望对此有所帮助。或来自其他任何人。谢谢。
  • 我已经编辑了我上面的原始帖子,以显示我在哪里;仍未解决;请参阅上面编辑部分中的代码和问题;希望得到更多帮助(任何人)。谢谢。
  • 嗨@Mauro - 仍然希望您的进一步意见。也仅供参考,我转发@@stackoverflow.com/q/49216555/1247334
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-21
相关资源
最近更新 更多