PHP脚本似乎“运行得太快”,无法等待表单提交上传和文件移动。

huangapple go评论65阅读模式
英文:

PHP Script appears to be "running too fast" to await form post uploads and file moves

问题

我在脚本中添加了一行 sleep(2);,在追加到电子邮件正文的步骤和附加到电子邮件的步骤之间。这有点确认脚本在进行得太快,现在可以附加并传递 600KB 文件。它们通过了病毒扫描部分,因此通过消息被添加到电子邮件正文,但文件未附加到电子邮件中。

英文:

I've built several forms in HTML/CSS with a single PHP script as the backend to handle sending an email from the form contents, and in 2 of the 3 forms, to attach the file uploads as an attachment after performing an AV scan, discarding the posted file name, and replacing with an assumed random name and tacking on the .ext of the original file. It works...most of the time.

The problem with the script seems related to file size. If the file is too big (5MB) then it doesn't finish posting before the script has run to completion, fired off the email, and moved on with life. 60KB files worked fine, 600KB files required me to add a sleep step between the email body step and the attach to email step.

Is my only choice to keep manually slowing down the script, or should my code be written differently?

Relevant HTML (IncludesBootstrap 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">&#x260e 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 Backend (stripped HTML from .php file, as it's just a navigation menu and a thanks for contact) :

<?php
	/**
	 * 	Dependancies : PHPMailer  - licensed as LGPL-2.1-only - https://github.com/PHPMailer/PHPMailer/blob/master/LICENSE
	 */
	use PHPMailer\PHPMailer\PHPMailer;
	use PHPMailer\PHPMailer\SMTP;
	use PHPMailer\PHPMailer\Exception;

	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'])){
			$formtype = $_POST['formType'];
			$permitted= array('Contact Us', 'Quote Request', 'Application');
		
			if (in_array($formtype, $permitted, $strict=true)){
				$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'])) {
				$total_count = count($_FILES['Resume']['name']);
				$email_body .='<tr><td><b>Number of Files Submitted: </b></td><td>'.$total_count.'</td></tr>';
				foreach ($_FILES['Resume']['error'] as $key => $error) {
					if ($error == UPLOAD_ERR_OK){ //Verify file uploaded correctly
						   $tmpFilePath = $_FILES['Resume']['tmp_name'][$key];
						$command = '/usr/local/cpanel/3rdparty/bin/clamdscan ' . $tmpFilePath;
						$out = '';
						$int = -1;
						exec($command, $out, $int);
						echo "<br><pre>";
						print_r($out);
						echo "</pre><b>".$int."</b><br>";
						if ($int == 0) {
							$origInfo = pathinfo($_FILES['Resume']['name'][$key]); 
							$origExt = $origInfo['extension']; 
							$origName = $origInfo['basename']; 
							$origHash = password_hash ($origName, PASSWORD_DEFAULT, array('cost' => 5 ));
							$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 {
		$mail->SMTPDebug = false; 
		$mail->isSMTP();                                            
		$mail->Host       = 'mail.*****.com';                     
		$mail->SMTPAuth   = true;                                   
		$mail->Username   = 'user@example.com';
		$mail->Password   = 'Password';                          
		$mail->SMTPSecure = 'tls';        							
		$mail->Port       = 80;                                    
        $mail->setFrom('contactus@example.com', 'Website Submission');
    	$mail->addAddress($recipient); 
    	$mail->addReplyTo($valid_email, $fname . ' ' . $lname); 
   		$mail->isHTML(true); 
    	$mail->Subject = $fname . ' ' . $lname . ' sent a request from the Foo Bar Widget 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.";
		}
	}else {
		die();
	}
?>

I added a sleep(2); line between the append to email body step and attach to email step. This sort of confirmed that the script was moving on "too fast", as now 600KB files are attached and delivered. They were passing the Virus Scan portion so the pass message was added to the email body, but the file was not attached to the email.

答案1

得分: 1

RiggsFolly 在上传或失败的面包屑上是完全正确的。我猜我真的没有完全理解 foreach ($_FILES['Resume']['error'] as $key => $error) { if ($error == UPLOAD_ERR_OK){ 的完整行为。

在 php.ini 文件中将 upload_max_filesize 从 2MB 更改为 20MB 解决了所有剩余的问题。我回去删除了 sleep(2); 行,它仍然运行得很好!谢谢你的帮助!

英文:

RiggsFolly was spot on with the upload or fail breadcrumb. I guess I didn't really didn't understand the full behaviour of foreach ($_FILES['Resume']['error'] as $key => $error) {
if ($error == UPLOAD_ERR_OK){

Changing upload_max_filesize from 2MB to 20MB in the php.ini file resolved all remaining issues. I went back and removed the sleep(2); line and it's still working great! Thank you for your help!

huangapple
  • 本文由 发表于 2023年3月4日 01:44:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75630289.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定