You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何加速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. 改用异步方式发送邮件,避免阻塞请求

同步发送邮件会让用户一直等到邮件发送完成才能得到响应,这是最拖速度的环节。你可以把邮件任务放到后台队列,让请求先返回,后台再慢慢处理:

简单实现方式:用文件队列+定时脚本

  1. 把邮件需要的信息(收件人、图片路径、表单内容)序列化后写入一个临时文件:
$mailData = [
    'contacts' => $contacts,
    'formData' => $_POST,
    'imagePaths' => $compressedImagePaths // 压缩后的图片路径数组
];
$queueFile = './mail_queue/' . uniqid() . '.json';
file_put_contents($queueFile, json_encode($mailData));
  1. 写一个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);
}
  1. 用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,比如25M
  • memory_limit: 建议设置为128M以上,避免处理大图片时内存不足

内容的提问来源于stack exchange,提问作者Gab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:29:27