表单到电子邮件 PHP 验证使用 PHPMailer 进行回退



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

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

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

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

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

如果我只使用function sendemail部分末尾的return $mail->send();,它会发送正常。 但是,如果我尝试提交表单时字段中没有任何内容,则没有任何反应。 所以我尝试添加我在某处找到的这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';有效? "确定"部分附着在什么上?

谢谢!


///

根据下面 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
?>

还。。。

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

2)毛罗还建议使用an $error & $success flag。那是什么,我该怎么做?

3)如果"名称"和/或"电子邮件"字段(可能还有其他字段)只是空的,我希望在上述catch中有自定义错误消息。Mauro 在上面编写了function validateEmpty代码,但我无法让它工作。我是否将其放在脚本中的错误位置或对它做错了其他事情?

3b) 在我看来,这个函数仅适用于"名称"字段,我是否必须为"电子邮件"字段复制它?

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

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

tl;DR:两种说法的计算结果都是true。最好返回truefalse而不是字符串,稍后再处理消息。

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

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

if('ok')

if ('Error info...')

PHP 通过将if语句(这是括号之间的部分)上的条件truefalse转换为boolean类型来评估该条件。PHP 中的字符串到布尔值的转换基本上如下:任何非空字符串的计算结果为TRUE(点击链接,检查第一个表,最后一列)。

因此,如果函数成功,则返回"ok","错误信息..."如果失败,这些都是非空字符串,并且评估为true,因此无论第一次电子邮件发送尝试是否顺利,您的脚本都会尝试发送第二次,并始终$msg设置为"电子邮件已发送!

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

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

    • 首先,使用 javascript 验证数据,以便您的用户获得即时反馈。
    • 然后,使用 PHP 验证它(也许创建一个新的validate()函数,可以使用filter_var()来验证电子邮件。
    • 最后,仅当前两个成功时才发送电子邮件。
  2. 为了遵循你的思维链,你应该评估sendemail()返回的字符串是否等于"ok":

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

    但是,与其计算两个不同的字符串('ok'或'Error info...'),不如让函数返回布尔值,并且由于PHPMailer的send()已经这样做了,只需保持它对它的注释:

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

    相反,触发错误的更简洁方法是抛出/捕获异常:

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

永远不要忘记阅读文档!

最新更新