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

实现每5秒发送CSV中邮件并展示输出的技术问询

问题分析与解决方案

原代码的核心问题

  • 后端PHP循环同步执行,调用mail()时会一次性发送所有邮件,没有实现间隔5秒发送的逻辑,$wait变量仅作用于前端JS,对后端发送流程无影响。
  • 前端用document.write会覆盖页面内容,且多个setTimeout同时触发计时,并非在上一封邮件发送完成后再等待5秒,无法实现依次间隔输出。
  • 将邮箱地址按空格拆分遍历的逻辑不合理,每个邮箱应对应一次独立的发送和输出操作。

方案一:后端控制间隔(适合少量邮件)

如果邮件数量不多,可直接在PHP循环中添加sleep(5)实现间隔,同时开启实时输出展示发送状态,注意调整PHP执行时间限制:

<?php
ini_set('max_execution_time', 0); // 关闭执行时间限制
ob_implicit_flush(true); // 开启实时输出
ob_end_flush();

$row = 1;
if (($handle = fopen("Email.csv", "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
        $to = trim(implode($data)); // 清理邮箱地址多余空格
        if (empty($to)) continue; // 跳过空行
        
        $subject = 'Your subject';
        $message = 'Your mail content';
        $headers = "From: ar742812@gmail.com";
        
        // 发送邮件并获取结果
        $sendResult = mail($to, $subject, $message, $headers);
        
        // 实时输出发送状态
        echo ($row) . ": 发送邮件到 {$to} " . ($sendResult ? "成功" : "失败") . "<br>";
        $row++;
        
        // 最后一封邮件无需等待
        if (!feof($handle)) {
            sleep(5);
        }
    }
    fclose($handle);
}
?>

方案二:前端控制+后端接口(适合大量邮件)

拆分发送逻辑为后端接口和前端控制,前端每隔5秒请求一次接口发送下一封邮件,避免后端长时间执行超时:

1. 后端接口(send_email.php)

<?php
session_start();
// 用会话存储已发送的行数
$currentRow = isset($_SESSION['current_row']) ? $_SESSION['current_row'] : 1;

$handle = fopen("Email.csv", "r");
if ($handle === FALSE) {
    echo json_encode(['success' => false, 'msg' => '无法打开CSV文件']);
    exit;
}

// 跳转到当前待发送的行
for ($i=1; $i<$currentRow; $i++) {
    fgetcsv($handle, 1000, ",");
}

$data = fgetcsv($handle, 1000, ",");
fclose($handle);

// 所有邮件已发送完成
if ($data === FALSE) {
    unset($_SESSION['current_row']);
    echo json_encode(['success' => false, 'msg' => '所有邮件已发送完成']);
    exit;
}

$to = trim(implode($data));
if (empty($to)) {
    $_SESSION['current_row'] = $currentRow + 1;
    echo json_encode(['success' => false, 'msg' => '跳过空邮箱']);
    exit;
}

$subject = 'Your subject';
$message = 'Your mail content';
$headers = "From: ar742812@gmail.com";

$sendResult = mail($to, $subject, $message, $headers);
$_SESSION['current_row'] = $currentRow + 1;

echo json_encode([
    'success' => $sendResult,
    'row' => $currentRow,
    'email' => $to,
    'msg' => $sendResult ? '发送成功' : '发送失败'
]);
?>

2. 前端页面(index.html)

<!DOCTYPE html>
<html>
<head>
    <title>邮件发送进度</title>
</head>
<body>
    <div id="progress"></div>

    <script>
        const progressDiv = document.getElementById('progress');
        let isSending = false;

        function sendNextEmail() {
            if (isSending) return;
            isSending = true;

            fetch('send_email.php')
                .then(response => response.json())
                .then(data => {
                    // 追加发送状态到页面
                    const statusItem = document.createElement('div');
                    statusItem.textContent = `${data.row}: 发送邮件到 ${data.email} - ${data.msg}`;
                    progressDiv.appendChild(statusItem);

                    // 未发送完则间隔5秒继续
                    if (data.msg !== '所有邮件已发送完成') {
                        setTimeout(() => {
                            isSending = false;
                            sendNextEmail();
                        }, 5000);
                    } else {
                        const finishItem = document.createElement('div');
                        finishItem.textContent = '=== 所有邮件发送完成 ===';
                        progressDiv.appendChild(finishItem);
                    }
                })
                .catch(error => {
                    const errorItem = document.createElement('div');
                    errorItem.textContent = `请求错误: ${error.message}`;
                    progressDiv.appendChild(errorItem);
                    isSending = false;
                    setTimeout(sendNextEmail, 5000);
                });
        }

        // 启动发送流程
        sendNextEmail();
    </script>
</body>
</html>

关键说明

  • 方案一适合邮件数量少的场景,后端直接控制间隔,无需前端交互。
  • 方案二更适合大量邮件,通过前端控制请求间隔,避免后端超时,同时实时展示进度。
  • 两种方案都需确保服务器上mail()函数配置正确(如sendmail或SMTP设置),否则邮件无法正常发送。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 12:31:00