PHP HTML - 将上传的文件发送到 Gmail
Posted
技术标签:
【中文标题】PHP HTML - 将上传的文件发送到 Gmail【英文标题】:PHP HTML - Sending uploaded files to Gmail 【发布时间】:2022-01-20 04:04:50 【问题描述】:早安,
我的目标是当客户上传他的文件时,它将被发送到我们的 Gmail,并附上文件。文件不应发送到我们的服务器,以防止可能的病毒。
我还参考了this website 以了解如何将文件发送到电子邮件。网站在用户上传后从服务器获取文件,但我们不能这样做。我们需要将文件直接发送到电子邮件。
我修改了代码,但是当我上传文件并单击“上传”时没有任何反应。我还在学习 html 和 php,希望有人能指导我了解我的代码有什么问题。请耐心等待我。
这部分代码从数据库中获取用户名和手机(我需要将其转发到电子邮件)
if(isset($valid_user_id) && !empty($valid_user_id))
$sql = "SELECT sno,emailid,fname,lname,mobile,address,city,state,country,status FROM member WHERE emailid='$valid_user_id'";
.... ... 这是要求用户上传文件的表单
<form method="post" name="uploadproof" id="uploadproof" enctype="multipart/form-data">
<input type="hidden" id="wrap" name="wrap" value="upload" />
<input type="hidden" id="userid" name="userid" value="<?php echo $valid_user_id; ?>" />
<input type="file" id="images" name="images[]" multiple="multiple" accept=".png,.jpg,.jpeg"/>
<input type="submit" id="upload" name="upload" class="send" value="Upload" style="float: none;padding:10px;" />
<span id="load"></span>
<br />
</form>
这部分代码是将附件发送到Gmail的php
$postData = $uploadedFile = $statusMsg = '';
$statusMsg = 'HELLO';
$msgClass = 'errordiv';
if(isset($_POST['upload']))
// Get the submitted form data
$postData = $_POST;
$email = $row[emailid];
$name = $row[fname];
$mobile = $row[mobile];
$country = $row[country];
$subject = $_POST['subject'];
$message = $_POST['message'];
// Upload attachment file
if(!empty($_FILES["images"]["name"]))
//Get the uploaded file information
$fileName = basename($_FILES["images"]["name"]);
echo $fileName;
//get the file extension of the file
$fileType = substr($fileName, strrpos($fileName, '.') + 1);
//get file size
$fileSize = $_FILES["images"]["size"]/1024; //size in KBs
// Allow certain file formats
$allowTypes = array('jpg', 'png', 'jpeg');
if(in_array($fileType, $allowTypes))
$uploadStatus = 1;
else
$uploadStatus = 0;
$statusMsg = 'Sorry, only JPG, JPEG, & PNG files are allowed to upload.';
if($uploadStatus == 1)
// Recipient
$toEmail = 'Operation@gmail.com';
// Sender
$from = 'help@ecz.com';
$fromName = 'ECZ Members KYC';
// Subject
$emailSubject = 'KYC Request Submitted by '.$name;
// Message
$htmlContent = '<h2>Contact Request Submitted</h2>
<p><b>Name:</b> '.$name.'</p>
<p><b>Email:</b> '.$email.'</p>
<p><b>Mobile:</b> '.$mobile.'</p>
<p><b>Country:</b> '.$country.'</p>
<p><b>Subject:</b> '.$subject.'</p>
<p><b>Message:</b><br/>'.$message.'</p>';
// Header for sender info
$headers = "From: $fromName"." <".$from.">";
if(!empty($fileName) && file_exists($fileName))
// Boundary
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x$semi_randx";
// Headers for attachment
$headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"$mime_boundary\"";
// Multipart boundary
$message = "--$mime_boundary\n" . "Content-Type: text/html; charset=\"UTF-8\"\n" .
"Content-Transfer-Encoding: 7bit\n\n" . $htmlContent . "\n\n";
// Preparing attachment
if(is_file($fileName))
$message .= "--$mime_boundary\n";
$fp = @fopen($fileName,"rb");
$data = @fread($fp,filesize($fileName));
@fclose($fp);
$data = chunk_split(base64_encode($data));
$message .= "Content-Type: application/octet-stream; name=\"".basename($fileName)."\"\n" .
"Content-Description: ".basename($fileName)."\n" .
"Content-Disposition: attachment;\n" . " filename=\"".basename($fileName)."\"; size=".filesize($fileName).";\n" .
"Content-Transfer-Encoding: base64\n\n" . $data . "\n\n";
$message .= "--$mime_boundary--";
$returnpath = "-f" . $email;
// Send email
$mail = mail($toEmail, $emailSubject, $message, $headers, $returnpath);
// Delete attachment file from the server
// @unlink($uploadedFile);
else
// Set content-type header for sending HTML email
$headers .= "\r\n". "MIME-Version: 1.0";
$headers .= "\r\n". "Content-type:text/html;charset=UTF-8";
// Send email
$mail = mail($toEmail, $emailSubject, $htmlContent, $headers);
// If mail sent
if($mail)
$statusMsg = 'Your contact request has been submitted successfully !';
$msgClass = 'succdiv';
$postData = '';
else
$statusMsg = 'Your contact request submission failed, please try again.';
亲切的问候
【问题讨论】:
您不能“直接”发送文件,除非先将其发送到您的服务器。当用户提交表单时,该文件将被放置在您服务器上的一个临时目录中,然后您的脚本需要决定如何处理它。 Multipart email 是一个复杂的话题,你真的应该使用像 PHPMailer 这样成熟的邮件库,而不是尝试自己实现。 @CBroe 你的意思是像这个网站上的梨图书馆吗? html.form.guide/email-form/php-email-form-attachment 当然,如果你喜欢,你可以使用 PEAR 包。不过,我说的是github.com/PHPMailer/PHPMailer,这或多或少是 PHP 的首选解决方案,在已经带有自己的邮件程序类的框架之外。 为什么不在您的服务器上安装病毒扫描程序... 【参考方案1】:我认为您(很可能)在这方面走错了路。
首先,就像CBroe
已经说过的那样,如果你想发送电子邮件,使用 PHPMailer 比手动完成所有这些事情要好得多。
但更重要的是,我认为你甚至不需要它。
由于您将从(网络)服务器 (PHP) 发送这些电子邮件,因此文件已经在您的服务器上(这就是神奇的 $_FILES
数组的工作原理,它接受接收到的文件并将它们存储在您的服务器 /tmp 目录之一)。
保护您自己或您的用户免遭通过此界面发送的恶意文件实际上是相当容易的(比发送电子邮件容易得多)。
考虑到您正在使用array('jpg', 'png', 'jpeg');
,很明显您只想接收基本图像文件。 JPEG 和 PNG 图像或多或少本质上是安全的(它们不包含任何可执行位)。所以唯一担心的是有人正在上传另一种文件,重命名为看起来像.png/jpg
。 (想想virus.exe.png
;或者其他一些恶意内容,重命名为some.jpg
)。
这些情况很容易预防。 提交表单后,您可以:
-
验证原始文件名的扩展名 (
['name']
) 是 png|jpg|jpeg 之一。您已经这样做了(我建议添加 strtolower($fileType)
以解决大小写混合的变化)。
验证 mimetype (['type']
) 是 image/jpeg 或 image/png
验证文件大小 > 0 并且
使用PHP的getimagesize()
分析图像,它会返回([0] width
、[1] height
和[2] IMAGETYPE constant
)验证前两个是>0
,最后一个是IMAGETYPE_JPEG
|IMAGETYPE_PNG
.
现在您可以确定您收到了有效的图像文件
(可选)如果您真的很偏执,您可以创建一个新的 png 图像并使用 PHP GD
或 ImageMagick
函数将提交的图像导入/覆盖在新图像上,然后使用该新图像文件而不是原始文件。 (虽然我认为没有真正的原因,但这将是避免假设的恶意 EXIF 数据之类的彻底方法。
现在您可以使用生成的文件名(例如<datetime>.png
或<submissionid>_image1.png
或类似名称来存储文件。或者使用preg_replace
过滤原始文件名(['name']
)以删除除基本单词字符之外的任何内容(例如字母和数字以及下划线/破折号)。这些方法中的任何一种都可以防止潜在的恶意文件名。
我要补充一点,如果您仍然更喜欢使用电子邮件的方法,还需要考虑其他一些安全问题。
由于这些潜在恶意(提交的)文件会通过电子邮件发送到您的 GMail 地址,因此您假设 Google 会阻止这些文件,或将它们重定向到您的垃圾邮件箱,您可能是对的。
但这只是图片的一半。 Google 还将意识到它已从 您的(邮件)服务器的 IP 地址发送病毒/恶意软件/等,并且可能在电子邮件中带有 From: noreply@yourdomain.com
标头。现在,您的域和您的服务器 IP 地址都将遭受一些声誉损害,这反过来又会导致您和您的同事发送的常规电子邮件越来越多地最终进入垃圾邮件箱它的预期目标(无论他们是否使用 gmail)。
【讨论】:
以上是关于PHP HTML - 将上传的文件发送到 Gmail的主要内容,如果未能解决你的问题,请参考以下文章
PHP 表单通过电子邮件发送的结果。我需要捕获表单中的上传文件