我在 HTML/CSS 中构建了多个表单,使用一个 PHP 脚本作为后端来处理从表单内容发送电子邮件,并且在 3 个表单中的 2 个中,在执行 AV 扫描后将文件上传作为附件附加,丢弃发布的文件名,并替换为假定的随机名称并添加原始文件的 .ext。它的工作......大部分时间。
脚本的问题似乎与文件大小有关。如果文件太大 (5MB),则在脚本运行完成、发送电子邮件并继续生活之前,它不会完成发布。 60KB 的文件工作正常,600KB 的文件需要我在电子邮件正文步骤和附加到电子邮件步骤之间添加一个睡眠步骤。
我唯一的选择是继续手动减慢脚本速度,还是我的代码应该以不同的方式编写?
相关 HTML(包括 Bootstrap 5 CSS):
<form name="applyNow" action="/post.php" method="POST" enctype="multipart/form-data">
<input type="hidden" id="formType" name="formType" value="Application">
<div class="mb-1">
<label for="FName" name="fNameLabel" class="form-label">First Name *</label>
<input type="text" class="form-control" id="FName" name="FName" aria-required="true" required>
</div>
<div class="mb-3">
<label for="LName" name="lNameLabel" class="form-label">Last Name *</label>
<input type="text" class="form-control" id="LName" name="LName" aria-required="true" required>
</div>
<div class="mb-3">
<label for="PhoneNumber" name="phoneLabel" id="phoneLabel" class="form-label">☎ Phone *</label>
<input type="tel" class="form-control" id="PhoneNumber" name="Phone" aria-required="true" aria-describedby="phoneHelp" required>
</div>
<div class="mb-3">
<label for="Email" name="eMailLabel" class="form-label">Email address </label>
<input type="email" class="form-control" id="Email" name="mail" aria-describedby="emailHelp" aria-required="false" >
<div id="emailHelp" class="form-text">Your Email will only be used to contact you for business purposes.</div>
</div>
<div class="form-check form-check-inline">
<label class="form-check-label" for="RadioLicensed">I have a valid driver's license.</label>
<input class="form-check-input" type="checkbox" name="LicensedRadio" id="RadioLicensed" value="Licensed">
<div id="DLHelp" class="form-text">A Valid License is required for all applicants.</div>
</div>
<div class="mb-3">
<label for="Comment" name="commentLabel" class="form-label">Comment/Remarks *</label>
<textarea type="text" class="form-control" id="Comment" name="Comment" aria-required="true" required rows="3"></textarea>
<div id="commentHelp" class="form-text">If your Resume is hosted in the cloud, you can paste the link here.</div>
</div>
<div class="mb-3">
<label for="Resume" name="resumeLabel" class="form-label">Resume</label>
<input type="file" multiple="multiple" class="form-control" id="Resume" name="Resume[]" aria-required="false" >
<div id="resumeHelp" class="form-text">To upload multiple files, select them all at once, or use a zip file.</div>
</div>
<button id="formSubmit" name="formSubmit" type="submit" class="btn btn-primary">Submit</button>
</form>
PHP 后端(从 .php 文件中剥离 HTML,因为它只是一个导航菜单和感谢联系):
<?php
/**
* File: post.php
* Version: 1.0
*
* Dependancies : PHPMailer - licensed as LGPL-2.1-only - https://github.com/PHPMailer/PHPMailer/blob/master/LICENSE
*
*/
// PHPMailer included Namespaces
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
/**
// PHPMailer Includes **!! UPDATE Path for LIVE !!**
require '../includes/PHPMailer/src/Exception.php';
require '../includes/PHPMailer/src/PHPMailer.php';
require '../includes/PHPMailer/src/SMTP.php';
*/
// PHPMailer - Dev Server - COMMENT FOR LIVE
require '../../includes/PHPMailer/src/Exception.php';
require '../../includes/PHPMailer/src/PHPMailer.php';
require '../../includes/PHPMailer/src/SMTP.php';
if($_SERVER['REQUEST_METHOD'] === "POST") { // If the PHP script is called via a POST request, proceed, else die();
if(isset($_POST['formType'])){ // Hidden input field required on all submitted forms. Some autosubmit spammer scripts will fill in all input types even if hidden, so check for valid hidden input, else die();
$formtype = $_POST['formType'];
$permitted= array('Contact Us', 'Quote Request', 'Application');
if (in_array($formtype, $permitted, $strict=true)){
//Valid Form Submission, Create new mailer and begin setting up the email body
//Create a new PHPMailer instance; passing `true` enables exceptions
$mail = new PHPMailer(true);
$email_body = '<!DOCTYPE html>
<html>
<head>
<meta charset="UTF8">
<link href="https://example.com/style/bootstrap.css" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Montserrat">
<link href="https://example.com/style/main.css" rel="stylesheet">
</head>
<body class="bg-light">
<div class="col-sm-8 offset-sm-2 text-center text-dark h5">
<img src="https://example.com/uploads/5/7/3/0/57306071/1452025426.png" alt="Foo Bar Widgets" class="img-fluid">
</div>
<div class="col-sm-8 offset-sm-2 text-center text-dark h5">
A new '.$formtype.' form has been posted from the Foo Bar Widgets site.
</div>
<br>
<div class="col-sm-8 offset-sm-2">
<table class="table">';
if(isset($_FILES['Resume'])) {
// Count the number of uploaded files in array
$total_count = count($_FILES['Resume']['name']);
echo "<br>Count: ".$total_count."<br>";
$email_body .='<tr><td><b>Number of Files Submitted: </b></td><td>'.$total_count.'</td></tr>';
// Loop through every file
foreach ($_FILES['Resume']['error'] as $key => $error) {
if ($error == UPLOAD_ERR_OK){ //Verify file uploaded correctly
$tmpFilePath = $_FILES['Resume']['tmp_name'][$key];
//Perform Virus Scan using ClamAV
$command = '/usr/local/cpanel/3rdparty/bin/clamdscan ' . $tmpFilePath;
// Dev Server Command - Comment for LIVE
$command = 'cat '.$tmpFilePath.' | clamdscan -';
$out = '';
$int = -1;
exec($command, $out, $int);
echo "<br><pre>";
print_r($out);
echo "</pre><b>".$int."</b><br>";
if ($int == 0) {
//Passed Virus Scan
//Setup our new file path
$origInfo = pathinfo($_FILES['Resume']['name'][$key]);
$origExt = $origInfo['extension'];
$origName = $origInfo['basename'];
$origHash = password_hash ($origName, PASSWORD_DEFAULT, array('cost' => 5 )); //.5x cost password hash (default cost 10) to get a unique? salted 60 digit hash of filename
$validHash = str_replace(array('\\','.','/',':','*','?','"','<','>','|',),'',$origHash);
$newName = substr($validHash,0,8).'.'.$origExt;
$subone = substr($validHash,24,2);
$subtwo = substr($validHash,28,2);
$basepath = "/home/***/public_html/uploads/";
$newFilePath = $basepath.$subone.'/'.$subtwo.'/'.$newName;
if(!file_exists($basepath.$subone)){
mkdir($basepath.$subone, 0755);
mkdir($basepath.$subone.'/'.$subtwo, 0755);
}else{
if(!file_exists($basepath.$subone.'/'.$subtwo)){
mkdir($basepath.$subone.'/'.$subtwo, 0755);
}
}
$append = 0;
while(file_exists($newFilePath)){
$newName = substr($validHash,0,8).'~'.$append.'.'.$origExt;
$newFilePath = $basepath.$subone.'/'.$subtwo.'/'.$newName;
$append++;
}
if (move_uploaded_file($tmpFilePath, "$newFilePath")) {
$email_body .= '<tr><td><b>File Uploaded:</b></td><td class="text-primary">'.$newFilePath.' - PASSED a ClamAV Scan</td></tr>';
sleep(2); // Added to allow file to copy from tmp directory to permanent home for files > 600KB
$mail->addAttachment($newFilePath);
}
} else {
$email_body .= '<tr><td><b>File Uploaded:</b></td><td class="text-danger">'.$tmpFilePath.' - FAILED a ClamAV Scan - it has been discarded.</td></tr>';
}
}
}
}
$email_body .= "</table></div></body></html>";
try {
//Server settings
$mail->SMTPDebug = false;
// $mail->SMTPDebug = SMTP::DEBUG_SERVER;
// $mail->SMTPDebug = SMTP::DEBUG_CLIENT;
// $mail->SMTPDebug - SMTP::DEBUG_CONNECTION; //Enable verbose debug output
$mail->isSMTP(); //Send using SMTP
$mail->Host = 'mail.*****.com'; //Set the SMTP server to send through
$mail->SMTPAuth = true; //Enable SMTP authentication
$mail->Username = '[email protected]'; //SMTP username
$mail->Password = 'Password'; //SMTP password
$mail->SMTPSecure = 'tls'; //Enable TLS encryption
$mail->Port = 80; //TCP port to connect to;
//Recipients
//It's important not to use the submitter's address as the from address as it's forgery,
//which will cause your messages to fail SPF checks.
//Use an address in your own domain as the from address, put the submitter's address in a reply-to
$mail->setFrom('[email protected]', 'Website Submission');
$mail->addAddress($recipient); //Add a recipient
$mail->addReplyTo($valid_email, $fname . ' ' . $lname); //Reply To Address is submitted address and First Name + Last Name
//Content
$mail->isHTML(true); //Set email format to HTML
$mail->Subject = $fname . ' ' . $lname . ' sent a request from the Bay Hill webpage!';
$mail->Body = $email_body;
$mail->send();
echo '<br><div class="text-dark text-center">Thank you for contacting us, ' . $fname . '. You will get a reply within 24 hours.</div>';
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error.";
}
//Insert Database manipulation here *not yet implemented*
}else {
die();
}
?>
我在附加到电子邮件正文步骤和附加到电子邮件步骤之间添加了
sleep(2);
行。这有点证实了脚本的移动“太快了”,因为现在附加并交付了 600KB 的文件。他们通过了病毒扫描部分,因此通过消息被添加到电子邮件正文中,但文件没有附加到电子邮件中。