使用 phpMailer 和 PHP 从表单发送文件附件
Posted
技术标签:
【中文标题】使用 phpMailer 和 PHP 从表单发送文件附件【英文标题】:Send File Attachment from Form Using phpMailer and PHP 【发布时间】:2012-07-30 15:20:03 【问题描述】:我在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
行下)才能发送附件。但是……
-
我应该在
process.php
文件的顶部放置什么来拉入文件uploaded_file
?喜欢使用$_FILES['uploaded_file']
从contact-us.php 页面拉入文件?
AddAttachment();
内部有什么内容可以用来附加文件并与电子邮件一起发送?此代码需要放在哪里?
请帮忙并提供代码!谢谢!
【问题讨论】:
将您的代码基于the example provided with PHPMailer,它不存在此处建议的答案的安全问题。 我今天发现的有用提示:在您发送电子邮件之前,不要在服务器上unlink
附件文件。
【参考方案1】:
试试:
if (isset($_FILES['uploaded_file']) &&
$_FILES['uploaded_file']['error'] == UPLOAD_ERR_OK)
$mail->AddAttachment($_FILES['uploaded_file']['tmp_name'],
$_FILES['uploaded_file']['name']);
基本示例也可以在here找到。
AddAttachment
的函数定义为:
public function AddAttachment($path,
$name = '',
$encoding = 'base64',
$type = 'application/octet-stream')
【讨论】:
我完全按照您的方式实现了您的代码(第一个框),但它仍然没有将其附加到电子邮件中。如果我使用ob_start();
然后$body = ob_get_contents();
这会产生负面影响吗?另外,有没有办法确保文件是从表单中附加的?
我认为这不会产生负面影响。我的代码检查文件是否实际已上传,并且上传没有错误,因此可能存在问题。如果你var_dump($_FILES); exit;
,你会看到什么?
我是个白痴——我的表单中有正确的操作,但是 JS 验证链接到不同的表单操作(没有文件上传也是如此)。太感谢了!!还有一个问题,如何将文件类型限制为仅图像、pdf、Word、Excel 和 CAD 文件?
你可以查看上传文件名的扩展名,但是这个真的不靠谱。文件的 mime 类型也会被发送,但这也是不可信的。如果您有 PHP 5.3 或更高版本,您可以使用finfo_file
() 尝试检测文件的 mime 类型,这将根据文件的内容识别 pdf、Word、excel 或各种图像类型。在 PHP 5.3 之前,您可以为其安装 Pecl 扩展。
还有一个问题……我怎样才能允许上传.dwg
文件?我不能为此罚款mime类型? (AutoCad) 我试过application/acad
但它不起作用。【参考方案2】:
无法从客户端 PC 附加文件(上传)
在 HTML 表单中我没有添加以下行,所以没有附件:
enctype="multipart/form-data"
在表格中添加以上行(如下)后,附件就完美了。
<form id="form1" name="form1" method="post" action="form_phpm_mailer.php" enctype="multipart/form-data">
【讨论】:
【参考方案3】:此代码帮助我发送附件....
$mail->AddAttachment($_FILES['file']['tmp_name'], $_FILES['file']['name']);
用上面的代码替换你的 AddAttachment(...) 代码
【讨论】:
【参考方案4】:使用此代码在 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> ';
?>
将此link 用作参考。
【讨论】:
【参考方案5】:这将完美地工作
<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";
?>
【讨论】:
【参考方案6】:您将使用$_FILES['uploaded_file']['tmp_name']
,这是 PHP 存储上传文件的路径(它是一个临时文件,在脚本结束时由 PHP 自动删除,除非您已将其移动/复制到其他地方)。
假设您的客户端表单和服务器端上传设置正确,您无需执行任何操作即可“拉入”上传。它会神奇地出现在 tmp_name 路径中。
请注意,您必须验证上传是否确实成功,例如
if ($_FILES['uploaded_file']['error'] === UPLOAD_ERR_OK)
... attach file to email ...
否则,您可能会尝试使用损坏/部分/不存在的文件制作附件。
【讨论】:
你能提供我在AddAttachment();
部分中实际放入的内容吗?【参考方案7】:
大家好,下面的代码对我来说非常好用。只需将 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>
【讨论】:
【参考方案8】:在我自己的情况下,我在表单上使用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
);
【讨论】:
以上是关于使用 phpMailer 和 PHP 从表单发送文件附件的主要内容,如果未能解决你的问题,请参考以下文章
我被难住了:如何使用 PHP Mailer 发送 HTML 表单
带有 PHPMailer 的 jQuery AJAX + PHP 表单