使用PHPMailer通过电子邮件发送PHP验证后备表格 [英] Form to Email PHP Validation fallback using PHPMailer

查看:105
本文介绍了使用PHPMailer通过电子邮件发送PHP验证后备表格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

i have a basic contact form on a website. i need to send the form results to 2 email addresses... 1) me, & 2) a confirmation to the person who submitted the form. the form results sent to the submitter has a different message in it.

我计划添加 jQuery验证& Ajax 但是首先,我想使PHP正常工作.因此,我认为我不需要大量的PHP验证,只需要基本的验证-如果关键字段为空,则显示错误消息,作为后备.

i plan to add jQuery validation & Ajax but first i want to get the PHP to work. so i don't think i need a lot of PHP validation, just a basic - if critical fields are empty, then error message, as a fallback.

我正在使用PHPMailer,但不幸的是,对于我缺乏PHP技能的人来说,他们的文档非常缺乏.但是经过大量的Google搜索,我已经能够拼凑出大部分有效的内容.这是我的代码,它使用一个小形式的(稍后将提供更多字段).

i'm using PHPMailer but unfortunately their documentation is sorely lacking for someone of my lack-of-php skills. but after much google'ing, i've been able to piece together something that mostly works. here is my code utilizing a small form (more fields to come later).

这确实将表格发送到两个电子邮件地址-很好!

this DOES send the form to both email addresses - great!

我遇到麻烦的部分是验证&错误/成功消息.

the part i'm having trouble with is the validation & error/success messages.

如果我只是在function sendemail部分的末尾使用return $mail->send();,它将发送正常.但是,如果我尝试提交该字段中没有任何内容的表单,则不会发生任何事情.所以我尝试添加在某处找到的if(!$mail->send()) {...else...}片段,它也可以使用有效的表单信息,但如果为空,则不能.

if i just use the return $mail->send(); at the end of the function sendemail section, it sends fine. but if i try to submit the form without anything in the fields, nothing happens. so i tried adding this if(!$mail->send()) {...else...} piece i found somewhere, and it also works with valid form info, but not if empty.

那么,我应该怎么用呢?还是与其他部分不同?

so, what should i use instead of this? or would it be something different to the end if/else part?

<?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';起作用? 确定"部分附在什么内容上?

as a sidenote, why does the return 'ok'; work? what does the 'ok' part attach to?

谢谢!


////////////////////////////////////////////////////////

基于建议&毛罗(Mauro)的编辑(在下面的帖子中有评论),这是我现在的位置...

based on the suggestions & edits by Mauro below (and in that posts comments), here is where i'm at now...

<?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目录中产生错误消息的文本文件?

1) Mauro suggested i log the error message using use error_log(). how do i do that? is that what produces the text file of error messages in the ftp directory?

2)Mauro还建议使用an $error & $success flag.那是什么我该怎么办?

2) Mauro also suggested using an $error & $success flag. what is that & how do i do it?

3)如果名称"和/或电子邮件"字段(可能还有其他字段)只是空的,我想在上面的catch中显示自定义错误消息. Mauro在上面编写了function validateEmpty代码,但我无法使其正常工作.我在脚本中的错误放置位置还是其他错误?

3) i want to have the custom error message in the above catch if the "name" &/or "email" fields (& possibly others) are simply empty. Mauro wrote the function validateEmpty code above, but i can't get it to work. do i have it in the wrong placement within the script or doing something else wrong with it?

3b)在我看来,此功能仅用于名称"字段,我是否必须将其复制用于电子邮件"字段?

3b) it looks to me like this function is just for the "name" field, do i have to duplicate it for the "email" field?

请记住... 我希望能够在此处进行SIMPLE验证,以防万一Javascript/Jquery由于某种原因而无法正常工作. 还请注意,上面的确正确地发送"了电子邮件;因此,现在我只是想获得验证&错误消息才能正常工作.

PLEASE REMEMBER... i want to be able to have a SIMPLE validation here as a fallback in case Javascript/Jquery isn't working for some reason. also note that the above DOES "send" the email correctly; so am now just trying to get the validation & error message to work right.

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

thank you for your time & expertise!

推荐答案

tl; dr:这两个语句的评估结果均为true.最好返回truefalse而不是字符串,并稍后再处理消息.

tl;dr: both statements evaluate to true. It's better to return true or false instead of strings and handle the message later.

首先,我会解决您的问题,然后,我会针对良好做法提出一些建议.

First I'll take care of your question, then I'll make some suggestions on good practices.

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

When you use return x; in PHP and most languages, you're "sending" x back to where you called the function. So, when your code is executed it will be read as:

if('ok')

if ('Error info...')

PHP通过将if语句(这是括号之间的部分)转换为 任何非空字符串评估为TRUE (点击链接,检查第一张表,最后一列).

PHP evaluates the condition on an if statement (this is the part between parenthesis) as true or false by converting it to the boolean type. The string to boolean conversion in PHP is basically as follows: any non-empty string evaluates as TRUE (follow the link, check first table, last column).

因此,如果函数成功,则返回"ok",如果失败,则返回"Error info ...",它们都是非空字符串,其值均评估为true,因此无论是否发送第一封电子邮件尝试进行顺利,您的脚本将尝试发送第二个脚本,并且始终将$msg设置为已发送电子邮件!".

So, your function is returning 'ok' if it succeeds, 'Error info...' if it fails, these are both non-empty strings and thereof evaluated as true, so no matter if the first email sending attempt went well, your script will try to send the second one, and will always set $msg to 'Email sent!'.

  1. 正如@Matt所建议的那样,最好始终自己验证数据,而不要依赖PHPMailer进行验证.尽管如果目标地址无效,PHPMailer会返回错误,但如果电子邮件无效,则最好不调用该库.所以:

  1. As @Matt suggested it's always best to validate the data by yourself instead of relying on PHPMailer to do so. Despite PHPMailer will return an error if the destination address is invalid, it's a good practice not to even call the library if the email is not valid. So:

  • 首先,使用javascript验证数据,以便您的用户得到即时反馈.
  • 然后,使用PHP进行验证(也许创建一个新的validate()函数,该函数可以使用
  • First, validate the data using javascript, so your user get's instant feedback.
  • Then, validate it using PHP (maybe create a new validate() function that may use filter_var() to validate emails.
  • Last, send the email only if the previous two were successful.

要遵循您的思路,您应该评估sendemail()返回的字符串是否等于'ok':

To follow your chain of thought, you should be evaluating if the string returned by sendemail() equals to 'ok' or not:

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

但是,与其评估两个不同的字符串("ok"或"Error info ..."),不如该函数返回布尔值,并且

But, instead of evaluating two different strings ('ok' or 'Error info...') it's better if the function returned boolean values instead, and since PHPMailer's send() already does, just keep it as you have it commented:

return $mail->send()

  • 您的最后一行使用的是$mail,您在函数内声明了该变量,但从未使用过global,因此该点将不可用,因为您正尝试获取属性(ErrorInfo),您将触发两个PHP通知:Undefined variableTrying to get a property from a non-object.您可以仅在函数顶部添加global $mail,这将使其在全局范围内可用(超出函数的作用域),但这被认为是不好的做法,因为在大段代码中,您可能会感到困惑.

  • Your last line is using $mail, a variable that you declared inside a function and you never made global, so it won't be available at that point and since you're trying to get a property (ErrorInfo) you'll be firing two PHP notices: Undefined variable and Trying to get a property from a non-object. You COULD just add global $mail at the top of the function and that will make it globally available (outside your function's scope) but this is considered a bad practice since in large pieces of code you might get confused.

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

    Instead, a neater way of firing the error would be to throw/catch an 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部分.

    Here, if there's a problem with the emails sending, your function will throw a generic exception and the catch part will be executed.

    更好

    如果您这样初始化PHPMailer:

    If you initialize PHPMailer like this:

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

    如果无法发送电子邮件,它将自行引发异常,您将能够捕获该异常:

    It will throw an exception by itself if it fails to send the email and you'll be able to catch the exception:

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

  • 永远不要忘记阅读文档

    这篇关于使用PHPMailer通过电子邮件发送PHP验证后备表格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆