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

Laravel批量发送邮件如何获取成功与失败邮箱ID列表?

批量发送邮件并获取成功/失败邮箱列表的解决方案

问题原因分析

你遇到的Mail::failures()和返回值为空的情况,通常有两个核心原因:

  1. 部分邮件驱动(比如log驱动)不会返回真实的发送失败状态;
  2. 批量发送时,部分SMTP服务器不会逐个返回单个邮箱的错误信息,仅返回整体发送结果,导致failures()无法捕获单邮箱失败。

同时循环单条发送效率低,下面提供两种可行的替代方案:


方案一:小批量拆分发送(同步场景)

将100个邮箱拆分为小批次发送,每次发送后即时捕获失败邮箱,同步统计成功/失败列表,既比单条循环快,又能准确获取状态:

$subject = "Test Email";
$emailList = ['dhaval@test','yasin@yopmail.com', ...]; // 你的100个邮箱列表
$batchSize = 20; // 按需调整批次大小,避免触发服务器发送限制
$successEmails = [];
$failedEmails = [];

foreach (array_chunk($emailList, $batchSize) as $batch) {
    Mail::send([], [], function ($message) use ($batch, $subject) {
        $message->to($batch)->subject($subject);
    });
    
    // 记录当前批次的失败邮箱
    $currentFailures = Mail::failures();
    $failedEmails = array_merge($failedEmails, $currentFailures);
    
    // 计算当前批次的成功邮箱(总批次减去失败列表)
    $currentSuccess = array_diff($batch, $currentFailures);
    $successEmails = array_merge($successEmails, $currentSuccess);
    
    // 重置失败列表,避免下一批次重复统计
    Mail::clearFailures();
}

// 输出结果
dd($successEmails, $failedEmails);

方案二:队列异步发送(推荐,适合大数量)

用Laravel队列异步处理邮件发送,既解决同步发送耗时问题,又能精准捕获每个邮箱的失败状态:

步骤1:创建邮件任务

php artisan make:job SendEmailToUser

步骤2:编写任务逻辑

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;

class SendEmailToUser implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $email;
    public $subject;

    // 任务重试次数(按需设置)
    public $tries = 3;

    public function __construct(string $email, string $subject)
    {
        $this->email = $email;
        $this->subject = $subject;
    }

    public function handle()
    {
        // 发送单个邮箱的邮件
        Mail::send([], [], function ($message) {
            $message->to($this->email)->subject($this->subject);
        });
    }

    // 任务失败时触发,记录失败邮箱
    public function failed(\Throwable $exception)
    {
        // 方式1:记录到日志
        Log::error("邮件发送失败:{$this->email},错误信息:{$exception->getMessage()}");
        
        // 方式2:存入数据库(需提前创建email_failures表)
        DB::table('email_failures')->insert([
            'email' => $this->email,
            'error_msg' => $exception->getMessage(),
            'created_at' => now()
        ]);
    }
}

步骤3:分发任务

$subject = "Test Email";
$emailList = ['dhaval@test','yasin@yopmail.com', ...];

foreach ($emailList as $email) {
    SendEmailToUser::dispatch($email, $subject);
}

结果统计

  • 成功邮箱:总邮箱列表减去数据库/日志中的失败邮箱
  • 失败邮箱:直接从email_failures表或日志中提取

额外注意事项

  • 确保邮件驱动配置为smtp而非log/array,否则无法捕获真实失败状态;
  • 部分SMTP服务商有发送频率限制,小批次发送时需调整batchSize避免被限流;
  • 队列方案需要配置好队列驱动(比如Redis、数据库)并启动队列监听:php artisan queue:work

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 13:45:14