【问题标题】:PHP Mail Form - Only one variable is submittingPHP 邮件表单 - 仅提交一个变量
【发布时间】:2017-08-01 19:28:51
【问题描述】:

我正在尝试设置一个 PHP 邮件表单。我从this guide 开始,并且一直在进行一些细微的修改。目前,我正在获取要提交的表单,我正在接收电子邮件,但只有在文本区域中写入的 cmets 才会填充电子邮件的正文。

我的 PHP 代码:

<?php
$recipient_email    = "my@email.com"; //recepient
$from_email         = "from@email.com"; //from email using site domain.


if(!isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
	die('Sorry, request must be Ajax POST'); //exit script
}

if($_POST){
    
    $sender_name 	= filter_var($_POST["name"], FILTER_SANITIZE_STRING); //capture sender name
    $sender_email 	= filter_var($_POST["email"], FILTER_SANITIZE_STRING); //capture sender email
    $phone_number   = filter_var($_POST["telephone"], FILTER_SANITIZE_NUMBER_INT);
    $subject        = "Contact Form Entry";
    $message 		= filter_var($_POST["comments"], FILTER_SANITIZE_STRING); //capture message

    $attachments = $_FILES['file_attach'];
	
    //php validation
    if(strlen($sender_name)<4){ // If length is less than 4 it will output JSON error.
        print json_encode(array('type'=>'error', 'text' => 'Name is too short or empty!'));
        exit;
    }
    if(!filter_var($sender_email, FILTER_VALIDATE_EMAIL)){ //email validation
        print json_encode(array('type'=>'error', 'text' => 'Please enter a valid email!'));
        exit;
    }
    if(!filter_var($phone_number, FILTER_SANITIZE_NUMBER_FLOAT)){ //check for valid numbers in phone number field
        print json_encode(array('type'=>'error', 'text' => 'Enter only digits in phone number'));
        exit;
    }
    if(strlen($message)<3){ //check emtpy message
        print json_encode(array('type'=>'error', 'text' => 'Too short message! Please enter something.'));
        exit;
    }

    
    $file_count = count($attachments['name']); //count total files attached
    $boundary = md5("whatever"); 
            
    if($file_count > 0){ //if attachment exists
        //header
        $headers = "MIME-Version: 1.0\r\n"; 
        $headers .= "From:".$from_email."\r\n"; 
        $headers .= "Reply-To: ".$sender_email."" . "\r\n";
        $headers .= "Content-Type: multipart/mixed; boundary = $boundary\r\n\r\n"; 
        
        //message text
        $body = "--$boundary\r\n";
        $body .= "Content-Type: text/plain; charset=ISO-8859-1\r\n";
        $body .= "Content-Transfer-Encoding: base64\r\n\r\n"; 
        $body .= chunk_split(base64_encode($message)); 

        //attachments
        for ($x = 0; $x < $file_count; $x++){       
            if(!empty($attachments['name'][$x])){
                
                if($attachments['error'][$x]>0) //exit script and output error if we encounter any
                {
                    $mymsg = array( 
                    1=>"The uploaded file exceeds the upload_max_filesize directive in php.ini", 
                    2=>"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form", 
                    3=>"The uploaded file was only partially uploaded", 
                    4=>"No file was uploaded", 
                    6=>"Missing a temporary folder" ); 
                    print  json_encode( array('type'=>'error',$mymsg[$attachments['error'][$x]]) ); 
					exit;
                }
                
                //get file info
                $file_name = $attachments['name'][$x];
                $file_size = $attachments['size'][$x];
                $file_type = $attachments['type'][$x];
                
                //read file 
                $handle = fopen($attachments['tmp_name'][$x], "r");
                $content = fread($handle, $file_size);
                fclose($handle);
                $encoded_content = chunk_split(base64_encode($content)); //split into smaller chunks (RFC 2045)
                
                $body .= "--$boundary\r\n";
                $body .="Content-Type: $file_type; name=".$file_name."\r\n";
                $body .="Content-Disposition: attachment; filename=".$file_name."\r\n";
                $body .="Content-Transfer-Encoding: base64\r\n";
                $body .="X-Attachment-Id: ".rand(1000,99999)."\r\n\r\n"; 
                $body .= $encoded_content; 
            }
        }

    }else{ //send plain email otherwise
       $headers = "From:".$from_email."\r\n".
        "Reply-To: ".$sender_email. "\n" .
        "X-Mailer: PHP/" . phpversion();

        $body = "Name: " . $sender_name . "\r\n";
        $body .= "Email: " . $sender_email . "\r\n";
        $body .= "Comments: " . $message . "\r\n";
        $body .= "Telephone: ".$phone_number . "\r\n";
    }
        
    $sentMail = mail($recipient_email, $subject, $body, $headers);
    if($sentMail) //output success or failure messages
    {       
        print json_encode(array('type'=>'done', 'text' => 'Thank you for your email'));
		exit;
    }else{
        print json_encode(array('type'=>'error', 'text' => 'Could not send mail! Please check your PHP mail configuration.'));  
		exit;
    }
}
?>

我一直在测试它,主要是没有图像附件,所以代码应该跳转到 }else{ //send plain email else 部分。

$body = "Name: " . $sender_name . "\r\n";
$body .= "Email: " . $sender_email . "\r\n";
$body .= "Comments: " . $message . "\r\n";
$body .= "Telephone: ".$phone_number . "\r\n";

包含此代码后,我想知道为什么所有这些行都没有连接到 body 变量中,并在 mail() 函数被触发时发送所有这些信息。我收到的电子邮件仅包含表格上textarea 中写的内容。有什么见解吗?

【问题讨论】:

  • '代码应该跳转'...你确定$file_count等于0吗?请运行var_dump($file_count);
  • 您的标头应该用\r\n 分隔,我猜它正在将其他行混入电子邮件标头中。
  • @PetervanderWal 完全不了解 PHP 的工作原理,因此不知道如何运行 var_dump,您的评论启发我完全删除 if/else 语句,只保留 else 块中的代码。这实际上最终发送了它应该发送的所有内容!所以我想这证实了问题出在 if 块中。现在,如何使一切与文件附件一起工作......

标签: php jquery ajax email


【解决方案1】:

由于循环中的“添加附件”代码正在检查空文件名,因此在 $file_count 语句中执行此操作也是安全的。

改变

$file_count = count($attachments['name']);

进入

$file_count = count(array_filter($attachments['name']));

因此只计算非空文件名。

【讨论】:

  • 太棒了,这让预期的 if/else 逻辑起作用。谢谢!关于将“电子邮件、cmets、电话等”连接到 $body 以在存在附件时显示所有这些信息的任何想法?带有附件的表单提交电子邮件的正文仅显示使用当前代码在 cmets 框中写入的内容。在以//message text 开头的代码块末尾添加更多信息不起作用。
  • 将邮件文本存储在一个新变量中(例如称为$mailText),然后将$message 替换为$mailText。额外提示(如果你得到了那个工作):将所有$mailText = ... 放在if 上方,这样你就可以在你的else-part($body = $mailText;)中使用相同的变量
  • 这适用于保存所有用户信息并在没有附件时发送,但带有附件的表单提交仍然只发送评论框文本(+附件)。我尝试了$body .= chunk_split(base64_encode($mailText));(这仅发送了评论框文本)并简单地将变量重置为$body = $mailText,就在其下方(这根本没有发送任何文本)。
  • 您是用$body .= chunk_split(base64_encode($mailText)); 替换了$body .= chunk_split(base64_encode($message)); 还是只是添加了那行?后者确实行不通。当然,您应该先用正确的文本填充 $mailText。
  • 我分别尝试了前者和后者。我实际上刚刚开始工作!我不得不在两个地方添加 mailText 变量,但它最终起作用了。一次在这里:imgur.com/iR1hGgk 一次在这里:imgur.com/qWR4lQo。感谢您的所有帮助!
猜你喜欢
  • 1970-01-01
  • 2013-03-18
  • 2016-02-14
  • 2011-04-02
  • 2018-11-05
  • 2016-01-07
  • 2013-09-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多