如何加速PHP的mail()代码?多图片发送时网站加载缓慢
优化多图片表单上传与邮件发送速度的方案
嘿,我碰到过不少类似的情况,多图片上传后发送邮件慢主要是因为同步处理大文件+同步发送邮件拖慢了整个请求流程,给你几个实操性强的优化方案:
1. 先压缩上传的图片,大幅减小文件体积
用户上传的原图往往几MB甚至十几MB,直接作为附件发送会极大增加传输时间。你可以在接收文件后先压缩图片,比如调整分辨率、降低画质:
function compressImage($sourcePath, $targetPath, $quality = 60) { // 获取图片信息 $info = getimagesize($sourcePath); if ($info['mime'] == 'image/jpeg') { $image = imagecreatefromjpeg($sourcePath); } elseif ($info['mime'] == 'image/png') { $image = imagecreatefrompng($sourcePath); imagealphablending($image, true); imagesavealpha($image, true); } else { return false; // 只处理常见格式 } // 按比例缩小(可选,比如限制宽高不超过1920px) $maxWidth = 1920; $width = imagesx($image); $height = imagesy($image); if ($width > $maxWidth) { $ratio = $maxWidth / $width; $newWidth = $maxWidth; $newHeight = intval($height * $ratio); $compressedImage = imagecreatetruecolor($newWidth, $newHeight); if ($info['mime'] == 'image/png') { imagealphablending($compressedImage, false); imagesavealpha($compressedImage, true); } imagecopyresampled($compressedImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height); imagejpeg($compressedImage, $targetPath, $quality); imagedestroy($compressedImage); } else { imagejpeg($image, $targetPath, $quality); } imagedestroy($image); return true; } // 处理上传的图片 foreach ($_FILES['images']['tmp_name'] as $key => $tmpName) { $originalPath = $tmpName; $compressedPath = './temp/compressed_' . $_FILES['images']['name'][$key]; compressImage($originalPath, $compressedPath); // 后续用压缩后的文件作为邮件附件 }
2. 改用异步方式发送邮件,避免阻塞请求
同步发送邮件会让用户一直等到邮件发送完成才能得到响应,这是最拖速度的环节。你可以把邮件任务放到后台队列,让请求先返回,后台再慢慢处理:
简单实现方式:用文件队列+定时脚本
- 把邮件需要的信息(收件人、图片路径、表单内容)序列化后写入一个临时文件:
$mailData = [ 'contacts' => $contacts, 'formData' => $_POST, 'imagePaths' => $compressedImagePaths // 压缩后的图片路径数组 ]; $queueFile = './mail_queue/' . uniqid() . '.json'; file_put_contents($queueFile, json_encode($mailData));
- 写一个PHP脚本
process_mail_queue.php,用来读取队列文件并发送邮件:
$queueDir = './mail_queue/'; $files = scandir($queueDir); foreach ($files as $file) { if ($file == '.' || $file == '..') continue; $filePath = $queueDir . $file; $mailData = json_decode(file_get_contents($filePath), true); // 这里用PHPMailer发送邮件,处理附件 // ... 邮件发送逻辑 ... // 发送成功后删除队列文件 unlink($filePath); }
- 用Linux的crontab设置定时任务,比如每分钟跑一次脚本:
* * * * * /usr/bin/php /path/to/process_mail_queue.php
更高效的方式:用Redis队列
如果服务器有Redis,可以用Redis的List结构做队列,比文件队列更高效,避免文件IO的开销。
3. 优化邮件发送逻辑,减少SMTP连接次数
如果你的代码是循环给每个收件人发邮件,那每次循环都要建立一次SMTP连接,非常耗时。改成用**密送(BCC)**一次性发送给所有收件人:
// 假设用PHPMailer $mail = new PHPMailer\PHPMailer\PHPMailer(); $mail->setFrom('your@domain.com'); $mail->Subject = '表单提交通知'; $mail->Body = '表单内容...'; // 把所有收件人添加到BCC foreach ($contacts as $contact) { $mail->addBCC($contact); } // 添加压缩后的图片附件 foreach ($compressedImagePaths as $path) { $mail->addAttachment($path); } // 只需要发送一次 $mail->send();
4. 检查PHP配置,确保上传和内存限制合理
打开php.ini检查以下配置,避免因为配置限制导致的隐性延迟:
upload_max_filesize: 建议设置为20M左右(根据你的需求调整)post_max_size: 要大于upload_max_filesize,比如25Mmemory_limit: 建议设置为128M以上,避免处理大图片时内存不足
内容的提问来源于stack exchange,提问作者Gab
相关产品推荐
相关产品推荐

