phpmailer +多个可能的文件上传 - >附件(我被困)

时间:2014-11-23 01:30:50

标签: php jquery ajax file-upload phpmailer

问候堆垛机,

提前抱歉这太久了!!!

我已经使用过php& js多年来,我仍然是一个写自己代码的菜鸟。由于缺乏聘请开发人员的资金,我已经被赋予了创建这个在线表格的任务,以便参与者填写&将文件上传到。

最终,目标是学习如何将表单提交进入mysql数据库&能够在屏幕上呈现结果。 但是 ,目前,我们很满意将表单结果通过电子邮件发送给我们。

到目前为止,我已经创建了所需的html / css表单,并且我已经实现了一种方法,通过ajax / jquery将表单提交到我的phpmailer代码,然后将结果发回给用户反馈成功或错误没有页面刷新。

已成功成功实现 with 文件上传/附件。并且我已经成功仅仅1 文件上传/附件。 但是 没有 成功地通过 超过1个 文件上传/附件来实现这一目标。

我知道我在php& amp;中错过了一些基本知识。 js,但是当我参与这个项目时,我一直在努力教自己。我已经阅读了很多,并尝试通过谷歌搜索在stackoverflow和其他地方找到的每个建议/教程。但是,我并没有"得到它"但由于某种原因。

真的可以使用一些帮助&除了这里,我也不知道还能去哪里问。我应该在几个星期前问过,但我不断在各个其他部分取得进展,我只是认为关键就在眼前。但现在我必须完成这项工作并且我不能再像以前那样浪费时间去浪费时间了。我祈求怜悯; - )

所以,如果它有助于了解更多背景/信息...

  • 表单页面是html(该页面中没有php)。
  • 我的头脑中有Jquery,Jquery.Easing,Jquery.Form, Jquery.Validate,Jquery.Validate.Additional.Methods,在一对夫妇中 其他我认为与此无关。
  • 我使用Jquery的Valdiate插件进行即时通用验证。
  • 我已经获得了文件上传的PHP验证代码作为后备。
  • 我们只关心现代浏览器(不需要黑客或后退 兼容性)。
  • 我使用名为EZDZ的Jquery插件来设置拖放选项 对于文件输入(https://github.com/jaysalvat/ezdz)。
  • 我有最新的phpmailer文件(class.phpmailer.php, class.smtp.php,&来自github页面的PHPMailerAutoload.php) (https://github.com/PHPMailer/PHPMailer)。
  • 我使用免费的Mandrill帐户(http://mandrill.com)发送 通过电子邮件 - 不是因为我真的了解它或任何东西,但是 因为有人建议我这样做,因为我无法让Gmail工作 用它。
  • 最后,唯一的表格项目是" required"是"名称", "电子邮件",&第一个文件上传及其附带的复选框组。 所有其他文件上传,复选框,文本输入等 可选的。

请记住,我已经将所有这些工作得很好而没有文件附件&只有1个文件附件。它有多种文件上传选项可以让我失望。

这是我的表单标记代码(所以你可以看到它,因为我在其他帖子中看到过这里引起了一些问题)......

<form name="cycleReports" id="cycleReports" class="cycleReports" action="/scripts/cycleReports-formProcessor.php" method="post" enctype="multipart/form-data" autocomplete="on">

我有一组复选框让我困扰了一段时间,但我终于能够弄明白如何通过在名称中使用空括号来解决这些问题。比如name="groupOfCheckboxes[]",然后找到一些代码来处理(下面)读取&#34;值&#34;每个复选框。但是我在其他地方读到,如果你没有&#34;值&#34;就像文件输入一样,你可以这样做......

<input type="file" name="cycleFile[cycleFileDocument1]" id="cycleFile-document1" class="cycleFile requireMe" />
<input type="file" name="cycleFile[cycleFileDocument2]" id="cycleFile-document2" class="cycleFile" />
<input type="file" name="cycleFile[cycleFileDocument3]" id="cycleFile-document3" class="cycleFile" />
<input type="file" name="cycleFile[cycleFileSupplement1]" id="cycleFile-supplemental1" class="cycleFile" />
<input type="file" name="cycleFile[cycleFileSupplement2]" id="cycleFile-supplemental2" class="cycleFile" />
<input type="file" name="cycleFile[cycleFileOther1]" id="cycleFile-other1" class="cycleFile" />

并且,如果它是相关的,这里是我的提交按钮加上js文件用于插入通知的3个div ...

<button type="submit" name="button" id="submit" class="submit">Submit Form</button>
<div class="errorMsgs"></div>
<div id="noteFailure"></div>
<div id="noteSuccess"></div>

这是我提供验证的JS / Ajax / Jquery文件的大部分内容。提交...

$(document).ready(function(){

    $.validator.addClassRules("requireMe", {
        required: true,
        minlength: 1
    });

    $.validator.addMethod('filesize', function(value, element, param) {
        var param = 10485760;
        return this.optional(element) || (element.files[0].size <= param)    
    });

    $.validator.addClassRules("fileValidations", {
        filesize: true,
        extension: "pdf|txt|jpg|png|mp3",
        accept:    "application/pdf,"
                  +"text/plain,"
                  +"image/jpeg,"
                  +"image/png,"
                  +"audio/mpeg,"
                  +"audio/mp3,"
    });

    $('#cycleReports').validate({
        focusCleanup: true,
        focusInvalid: false,
        onkeyup: false,
        errorClass: "barf",
        validClass: "booyahh",

        errorPlacement: $.noop, // disable default messages
        errorLabelContainer: $("div.errorMsgs"),
        errorElement: 'p',

        rules: { 
            uploaderName: {
                required: true
            },
            uploaderEmail: {
                required: true,
                email: true
            },
            'cycleDoc1Type[]': {
                required: true,
            },
        },

        highlight: function(element, errorClass, validClass) {
            $(element).addClass(errorClass).removeClass(validClass);
            $(element).parents('div.formItem').addClass(errorClass).removeClass(validClass);
            $(element).parents('div.ezdz-dropzone').addClass(errorClass).removeClass(validClass);
        },

        unhighlight: function(element, errorClass, validClass) {
            $(element).removeClass(errorClass).addClass(validClass);
            $(element).parents('div.formItem').removeClass(errorClass).addClass(validClass);
            $(element).parents('div.ezdz-dropzone').removeClass(errorClass).addClass(validClass);
        },

        messages: {
            uploaderName: "Please specify your name.",
            uploaderEmail: {
                required: "We need your email address in case we have a question.",
                email: "Your email address must be in the format of name@domain.com"
            },
            'cycleDoc1Type[]': "A Cycle Document needs at least one check to identify it's kind.",
            cycleFileDocument1: "Only standard document filetypes under 10 MB's are acceptable.",
        },

        submitHandler: function(form) { // Use Ajax to send everything to the form Processor php file
            showAJAXLoader(); // config.progressbar.js
            $(form).ajaxSubmit({ // ajaxSubmit function submits the form without a page refresh to another URL.
                // Should the result be successful, call this function. 
                // After the submission, this function is called. 
                    // responseText is the text which is returned from the server. 
                    // statusText is the HTTP Status Code. 
                    // xhr is the XMLHttpRequest object used. 
                    // $form is the form element that was processed.
                success: function(responseText, statusText, xhr, $form) {
                    var res = jQuery.parseJSON(responseText);
                        if(res.error){
                            hideAJAXLoader(); // config.progressbar.js
                            $("#noteFailure").html(res.msg).hide().slideDown("fast");
                                window.setTimeout(function(){
                                    $("#noteFailure").hide(500)
                                }, 8000);
                        }else{
                            hideAJAXLoader(); // config.progressbar.js
                            $(form).slideUp("fast"); // Now, after submission, if successful, sliding the form up only showing notification
                            $("#noteSuccess").html(res.msg).hide().slideDown("fast"); // This puts the return value of the AJAX call into the #response div.
                        } // END if/else
                  } // END success: function()
            }); // END ajaxSubmit
        return false; // This stops the form from normal submission.
        } // END submitHandler
    }); // END validate
}); // END function

好的,所以,这是我的PHP文件的一部分...

$return = array('error'=>0);

    $uploaderName =         $_POST['uploaderName']; // TEXT INPUT
    $uploaderEmail =        $_POST['uploaderEmail']; // TEXT INPUT
    $uploaderRole =         $_POST['uploaderRole']; // DROPDOWN SINGLE SELECTION
    $uploaderSchool =       $_POST['uploaderSchool']; // DROPDOWN SINGLE SELECTION

    $gradeRange =           $_POST['gradeRange']; // THIS IS A GROUP OF CHECKBOXES gradeRange[]
    $cycleSubject =         $_POST['cycleSubject']; // DROPDOWN SINGLE SELECTION
    $lessonTopic =      $_POST['lessonTopic']; // TEXT INPUT
    $pedagogicalFocus =     $_POST['pedagogicalFocus']; // DROPDOWN SINGLE SELECTION

    $cycleDoc1Type =        $_POST['cycleDoc1Type']; // THESE 4 ARE GROUPS OF CHECKBOXES THAT PERTAIN TO EACH OF THE 1ST 4 FILE UPLOADS
    $cycleDoc2Type =        $_POST['cycleDoc2Type'];
    $cycleDoc3Type =        $_POST['cycleDoc3Type'];
    $cycleDoc4Type =        $_POST['cycleDoc4Type'];

    $cycleDoc1OtherDesc =   $_POST['cycleDoc1OtherDesc']; // THESE 2 TEXT INPUTS PERTAIN TO THE LAST 2 FILE UPLOADS
    $cycleDoc2OtherDesc =   $_POST['cycleDoc2OtherDesc'];

    $cycleFile =            $_POST['cycleFile']; // THIS IS THE FILE INPUT FIELDS cycleFile[]

现在,如果我只有1个文件输入,这里的代码是可以工作 ...

$allowedExts = array( "pdf", "txt", "jpg", "png", "mp3");

$allowedMimeTypes = array(
    'application/pdf',
    'text/plain',
    'image/jpeg',
    'image/png',
    'audio/mpeg', 
    'audio/mp3',
    );

$temp = explode('.', $_FILES['uploaderFile']['name']);

$dest_file = '/home/vandytpeg/public_html/temp/' . time() . '-' . $_FILES['uploaderFile']['name'];

$extension = end($temp);

if (( $_FILES['uploaderFile']['size'] < 10485760) && in_array($extension, $allowedExts)) {   // 5242880 bytes = 5MB, 10485760 = 10 MB, 52428800 = 50 MB

    move_uploaded_file($_FILES['uploaderFile']['tmp_name'], $dest_file);

} else { //execute if filesize is too large & if extension doesn't match accepted
    $return['error'] = 1;
    $return['msg'] =  "<span class='failure'>Only the specified file-type that are under 10 MB are allowed!";
}   

...我拿出上面的代码(为了安全保存),并试图将其变形为适用于潜在多个文件的东西。并且这里是我被困的地方(我认为)。这是在添加多个文件上传选项后我已经走了多远。我不确定它的任何部分是否正确&#34;究竟。所以我希望有人可以帮助我这部分(以及其他人)......

$numbFiles = count(array_filter($_FILES['cycleFile']['name']));

$allowedExts = array( "pdf", "txt", "jpg", "png", "mp3");

$allowedMimeTypes = array(
    'application/pdf',
    'text/plain',
    'image/jpeg',
    'image/png',
    'audio/mpeg', 
    'audio/mp3',
    );

$temp = explode('.', $_FILES['cycleFile']['name']);

$extension = end($temp);

$finfo = new finfo(FILEINFO_MIME); //??? NOT SURE IF THIS IS RIGHT OR NOT

$mime = $finfo->file($_FILES['cycleFile']['tmp_name']);  

for ($i = 0; $i < $numbFiles; ++$i) {

    $dest_file = '/home/vandytpeg/public_html/temp/' . time() . '-' . $_FILES['cycleFile']['name'][$i];

    if (in_array($mime, $allowedMimeTypes) 
        && filesize($_FILES['cycleFile']['size'] < 10485760)
        && in_array($extension, $allowedExts)) {

            move_uploaded_file($_FILES['cycleFile']['tmp_name'][$i], $dest_file);

    } else { //execute if does not validate
        $return['error'] = 1;
        $return['msg'] =  "<span class='failure'>MAMMAMIA Only the specified file-type that are under 10 MB are allowed!";
    }   
}

这是电子邮件准备部分的开始(只是因为你看到我有必要的phpmailer东西)...

if(!$return['error']){  

    date_default_timezone_set('America/Chicago');

    require 'PHPMailerAutoload.php';

    $mail = new PHPMailer;

    $mail->IsSMTP();
    $mail->isHTML(true);

...之后我有Mandril HOST,PORT,SMTPAuth,USR,PWD,东西,以及SETFROM,ADDADDRESS,&amp; SUBJECT电子邮件标题。

然后我有像这样的html电子邮件中列出的表单项(这里只显示一个例子)...

$mail->Body  = "<p><strong>Uploader's Name:</strong><br />";
$mail->Body .= $uploaderName;
$mail->Body .= "</p>";

...我之后的每个重复版都有纯文本版本,但改为使用$mail->AltBody

现在,这里是我前面提到过的那些复选框的代码,这些代码让我长时间难以理解。我终于从其他各种帖子中找到了这一点(在isset&amp; empty等之间回过头来了;我不是真正理解差异或者是什么&#34;设置&#34;意味着,但是这个似乎工作)。如果没有&#34; 必要&#34;,最好在最后一次检查选择之后弄清楚如何 NOT 有一个尾随逗号,或者是否有&#39; ;只有1 ...

$mail->Body .= "<p><strong>Grade Range:</strong><br />";
if (isset($gradeRange))
    { 
    foreach($gradeRange as $gradeRangeValue)
        { 
          $mail->Body .= $gradeRangeValue .", "; // HOW TO NOT HAVE A COMMA AFTER THE LAST OPTION NOR IF ONLY ONE OPTION THAT WAS CHECKED?
        } 
    //unset($value); // IS THIS NEEDED? SEEMS TO WORK WITHOUT IT
    } 
else 
    {
    $mail->Body .= ""; // If no options selected, leave blank
    };          

在此之下,我需要显示为第一个所需文件上传选择的复选框选项以及它们存在的后续3个IF。我借用了上面的大复选框组使用的代码。但我被困这里(我认为)是如何列出附件的文件名以供参考。我只会粘贴前两个以节省空间。我相信我可以随后应用其他任何解决方案......

$mail->Body .= "<p><strong>Checked Option(s) of 1st Attached File (". $dest_file[$i] ."):</strong><br />"; // HOW TO LIST THE FILE NAME HERE?
if (isset($cycleDoc1Type)) { // THIS IS THE 4 CHECKBOXES PERTAINING TO THE FIRST SPECIFIC FILE
  foreach($cycleDoc1Type as $cycleDoc1Type_Cked) { 
       $mail->Body .= $cycleDoc1Type_Cked .", "; }} else { $mail->Body .= ""; }; // USING SAME PATTERN AS FOR GRADERANGE
$mail->Body .= "</p>";
$mail->Body .= "<p><strong>Checked Option(s) if 2nd Attached File (". $dest_file[$i] ."):</strong><br />";
if (isset($cycleDoc2Type)) { 
  foreach($cycleDoc2Type as $cycleDoc2Type_Cked) { 
       $mail->Body .= $cycleDoc2Type_Cked .", "; }} else { $mail->Body .= ""; };    
$mail->Body .= "</p>";

然后,对于上传任何文件的实际附加部分......

$mail->AddAttachment($dest_file);

...代码如果只有1个文件上传要附加。我无法弄清如何为附加的任何文件执行此操作。到目前为止,我在调查中得到了两个运行理论......

    foreach($numbFiles as $dest_file)
    {
        $mail->AddAttachment($dest_file);
    }
////// or ????
    if (isset($cycleFile))
        { 
        foreach($numbFiles as $dest_file)
            { 
            $mail->AddAttachment .= ": ". $dest_file ." :";
            } 
        } 
    else 
        {
        $mail->AddAttachment .= "";
        }   

最后,就目前而言,发送邮件&amp;将信息发送回js-&gt; html页面进行通知(这部分确实有效,如我所提到的,如果没有文件或只有1个文件但没有多个文件发送)......

    if(!$mail->Send()) {

        $return['error'] = 1;
        $return['msg'] = "Mailer Error: " . $mail->ErrorInfo;   // ErrorInfo holds the most recent mailer error message

     } else {

            $return['msg'] = "<span class='success'>Success! Your Cycle Report has been sent."; // THIS IS THE GREEN SUCCESS MESSAGE

            //unlink($dest_file); // NOT SURE IF THIS IS NEEDED ANYMORE DUE TO USING "move_uploaded_file" ABOVE
            }

} // closes: if(!$return['error']){ 


echo json_encode($return); 
die();

我得到的唯一错误是在javascript浏览器控制台中,这对我来说非常神秘。其他时候那里没有错误,但表格仍然挂起。

现在奇怪的是,使用此代码,如果我尝试在不上传文件的情况下发送(如果我禁用&#34;必需&#34;就可以了),那么按下提交后html页面就会粘贴只是js微调器。但电子邮件实际上确实来了。如果我尝试上传文件,同样的事情发生但我没有收到电子邮件。

所以,我知道我错过了相应的代码来向我显示错误&amp;它挂在哪里。那是我还没学到的另一部分。

我知道这是长期的(轻描淡写?);只是不知道如何提供所有需要的信息。 所以,如果你已经做到这一点,那么可以提供帮助,非常感激。

尝试摘要

PRIORITY ...

  • 使用1个必需但可能的多个文件输入来上传文件,将其作为附件发送到电子邮件中,&amp;然后将它们从服务器上删除。

欲望...

  • 在电子邮件中的复选框选项之间呈现逗号,但不是在最后一次选择之后,也不是只有一个。
  • 在电子邮件正文中呈现每个附件的文件名。
顺便说一下:我可能会&#39;愿意/能够支付每周一次的导师/教练来帮助我学习javascript / jquery(1st)。需要考虑的事情: - )

PS:请不要以为我应该知道事情,所以请不要在你的答案中隐晦或简短。致谢!!!

0 个答案:

没有答案