使用phpMailer和PHP从表单发送文件附件


72

我有一个example.com/contact-us.php看起来像这样的表格(简化):

<form method="post" action="process.php" enctype="multipart/form-data">
  <input type="file" name="uploaded_file" id="uploaded_file" />
  <input type="hidden" name="MAX_FILE_SIZE" value="10000000" />
</form>

在我的process.php文件中,我使用以下代码PHPMailer()来发送电子邮件:

require("phpmailer.php");

$mail = new PHPMailer();

$mail->From     = me@example.com;
$mail->FromName = My name;
$mail->AddAddress(me@example.com,"John Doe");

$mail->WordWrap = 50;
$mail->IsHTML(true);

$mail->Subject  =  "Contact Form Submitted";
$mail->Body     =  "This is the body of the message.";

电子邮件正确发送了正文,但没有附件uploaded_file

我的问题

我需要将uploaded_file表单中的文件附加到电子邮件中并发送出去。process.php脚本通过电子邮件发送文件后,我不在乎保存文件。

我知道我需要在AddAttachment();某处(我假设在此Body行下)添加附件以进行发送。但...

  1. 我要放在process.php文件顶部的什么位置才能拉入文件uploaded_file?像是$_FILES['uploaded_file']用来从contact-us.php页面提取文件的东西吗?
  2. AddAttachment();与电子邮件一起附加和发送的文件里面有什么内容,此代码需要放在哪里?

请帮助并提供代码!谢谢!


2
您的代码基于PHPMailer提供的示例该示例不存在此处建议的答案的安全性问题。
同步

1
我今天想出的有用提示:unlink在发送电子邮件之后,不要在服务器上添加附件文件。
Blazemonger'1

Answers:


109

尝试:

if (isset($_FILES['uploaded_file']) &&
    $_FILES['uploaded_file']['error'] == UPLOAD_ERR_OK) {
    $mail->AddAttachment($_FILES['uploaded_file']['tmp_name'],
                         $_FILES['uploaded_file']['name']);
}

基本示例也可以在这里找到。

函数定义为AddAttachment

public function AddAttachment($path,
                              $name = '',
                              $encoding = 'base64',
                              $type = 'application/octet-stream')

1
我完全按照您的方式实施了您的代码(第一个方框),但仍未将其附加到电子邮件中。如果我正在使用ob_start();,那么$body = ob_get_contents();会对您产生负面影响吗?另外,有没有办法确保文件是从表单附加的?
2012年

我认为这不会产生负面影响。我的代码检查是否确实上传了文件,并且上传没有错误,所以那里可能有问题。您会看到什么var_dump($_FILES); exit;
drew010

我是个白痴-我的表单中有正确的操作,但是JS验证链接到其他表单操作(没有文件上传也是如此)。非常感谢!!还有一个问题,如何将文件类型限制为仅图像,pdf,Word,Excel和CAD文件?
adamdehaven 2012年

您可以检查上载文件名的扩展名,但这实际上是不可信的。文件的mime类型也会被发送,但这也不能被信任。如果您具有PHP 5.3或更高版本,则可以使用finfo_file()尝试检测文件的mime类型,该文件根据文件的内容识别pdf,Word,excel或各种图像类型。在PHP 5.3之前,您可以为其安装Pecl扩展。
drew010

另一个问题...我如何允许.dwg文件上传?我不能为此罚款吗?(AutoCad)我试过了,application/acad但是不起作用。
adamdehaven 2012年

7

无法从客户端PC附加文件(上传)

在HTML表单中,我没有添加以下行,因此没有附件:

enctype =“ multipart / form-data”

在表格中添加以上行(如下所示)后,附件就完美了。

<form id="form1" name="form1" method="post" action="form_phpm_mailer.php"  enctype="multipart/form-data">

1

此代码可帮助我进行附件发送...。

$mail->AddAttachment($_FILES['file']['tmp_name'], $_FILES['file']['name']);

用上面的代码替换您的AddAttachment(...)代码


1

这将完美地工作

    <form method='post' enctype="multipart/form-data">
    <input type='file' name='uploaded_file' id='uploaded_file' multiple='multiple' />
    <input type='submit' name='upload'/> 
    </form>

    <?php
           if(isset($_POST['upload']))
        {
             if (isset($_FILES['uploaded_file']) && $_FILES['uploaded_file']['error'] == UPLOAD_ERR_OK)
                {
                     if (array_key_exists('uploaded_file', $_FILES))
                        { 
                            $mail->Subject = "My Subject";
                            $mail->Body = 'This is the body';
                            $uploadfile = tempnam(sys_get_temp_dir(), sha1($_FILES['uploaded_file']['name']));
                        if (move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $uploadfile))
                             $mail->addAttachment($uploadfile,$_FILES['uploaded_file']['name']); 
                            $mail->send();
                            echo 'Message has been sent';
                        }       
                else
                    echo "The file is not uploaded. please try again.";
                }
                else
                    echo "The file is not uploaded. please try again";
        }
    ?>

0

你会用 $_FILES['uploaded_file']['tmp_name'],这是PHP存储上载文件的路径(这是一个临时文件,脚本结束时PHP会自动将其删除,除非您将其移动/复制到其他位置)。

假设您的客户端表单和服务器端上载设置正确,则无需“上载”上载。它将神奇地在该tmp_name路径中可用。

请注意,您将必须验证上传是否成功,例如

if ($_FILES['uploaded_file']['error'] === UPLOAD_ERR_OK) {
    ... attach file to email ...
}

否则,您可能会尝试使用损坏/部分/不存在的文件进行附件处理。


您能为我提供我实际在AddAttachment();零件中提供的内容吗?
adamdehaven 2012年

0

使用此代码通过phpmailer中的html表单发送带有上传文件选项的附件

 <form method="post" action="" enctype="multipart/form-data">


                    <input type="text" name="name" placeholder="Your Name *">
                    <input type="email" name="email" placeholder="Email *">
                    <textarea name="msg" placeholder="Your Message"></textarea>


                    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
                    <input type="file" name="userfile"  />


                <input name="contact" type="submit" value="Submit Enquiry" />
   </form>


    <?php




        if(isset($_POST["contact"]))
        {

            /////File Upload

            // In PHP versions earlier than 4.1.0, $HTTP_POST_FILES should be used instead
            // of $_FILES.

            $uploaddir = 'uploads/';
            $uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

            echo '<pre>';
            if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
                echo "File is valid, and was successfully uploaded.\n";
            } else {
                echo "Possible invalid file upload !\n";
            }

            echo 'Here is some more debugging info:';
            print_r($_FILES);

            print "</pre>";


            ////// Email


            require_once("class.phpmailer.php");
            require_once("class.smtp.php");



            $mail_body = array($_POST['name'], $_POST['email'] , $_POST['msg']);
            $new_body = "Name: " . $mail_body[0] . ", Email " . $mail_body[1] . " Description: " . $mail_body[2];



            $d=strtotime("today"); 

            $subj = 'New enquiry '. date("Y-m-d h:i:sa", $d);

            $mail = new PHPMailer(); // create a new object


            //$mail->IsSMTP(); // enable SMTP
            $mail->SMTPDebug = 1; // debugging: 1 = errors and messages, 2 = messages only ,false = Disable 
            $mail->Host = "mail.yourhost.com";
            $mail->Port = '465';
            $mail->SMTPAuth = true; // enable 
            $mail->SMTPSecure = true;
            $mail->IsHTML(true);
            $mail->Username = "admin@domain.net"; //from@domainname.com
            $mail->Password = "password";
            $mail->SetFrom("admin@domain.net", "Your Website Name");
            $mail->Subject = $subj;
            $mail->Body    = $new_body;

            $mail->AddAttachment($uploadfile);

            $mail->AltBody = 'Upload';
            $mail->AddAddress("recipient@domain.com");
             if(!$mail->Send())
                {
                echo "Mailer Error: " . $mail->ErrorInfo;
                }
                else
                {

                echo '<p>       Success              </p> ';

                }

        }



?>

使用此链接作为参考。


0

大家好,下面的代码对我来说很好用。只需将setFrom和addAddress替换为您的首选项即可。

<?php
/**
 * PHPMailer simple file upload and send example.
 */
//Import the PHPMailer class into the global namespace
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
$msg = '';
if (array_key_exists('userfile', $_FILES)) {
    // First handle the upload
    // Don't trust provided filename - same goes for MIME types
    // See http://php.net/manual/en/features.file-upload.php#114004 for more thorough upload validation
    $uploadfile = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['userfile']['name']));
    if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) 
    {
        // Upload handled successfully
        // Now create a message

        require 'vendor/autoload.php';
        $mail = new PHPMailer;
        $mail->setFrom('info@example.com', 'CV from Web site');
        $mail->addAddress('blabla@gmail.com', 'CV');
        $mail->Subject = 'PHPMailer file sender';
        $mail->Body = 'My message body';

        $filename = $_FILES["userfile"]["name"]; // add this line of code to auto pick the file name
        //$mail->addAttachment($uploadfile, 'My uploaded file'); use the one below instead

        $mail->addAttachment($uploadfile, $filename);
        if (!$mail->send()) 
        {
            $msg .= "Mailer Error: " . $mail->ErrorInfo;
        } 
        else 
        {
            $msg .= "Message sent!";
        }
    } 
        else 
        {
            $msg .= 'Failed to move file to ' . $uploadfile;
        }
}
?>
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>PHPMailer Upload</title>
</head>
<body>
<?php if (empty($msg)) { ?>
    <form method="post" enctype="multipart/form-data">
        <input type="hidden" name="MAX_FILE_SIZE" value="4194304" />
        <input name="userfile" type="file">
        <input type="submit" value="Send File">
    </form>

<?php } else {
    echo $msg;
} ?>
</body>
</html>

0

就我自己而言,我serialize()在表单上使用,因此文件没有发送到php。如果您使用的是jquery,请使用FormData()。例如

<form id='form'>
<input type='file' name='file' />
<input type='submit' />
</form>

使用jQuery,

$('#form').submit(function (e) {
e.preventDefault();
var formData = new FormData(this); // grab all form contents including files
//you can then use formData and pass to ajax

});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.