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

Laravel8 给不同邮箱发送对应专属内容邮件的错误排查求助

问题排查与修复方案

基础信息

现有邮箱数组

array:2 [
  0 => array:2 [
    0 => "email1@gmail.com"
    1 => "email2@gmail.com"
  ]
  1 => array:1 [
    0 => "email3@gmail.com"
  ]
]

分公司表存储结构

id_filialeadm_emails
1["email1@gmail.com","email2@gmail.com"]
2["email3@gmail.com"]

需求

遍历邮箱列表,给每个邮箱发送对应关联的id_filiale下的待续约合同数据。

原有代码问题分析

第一版代码问题

Mail::send([], [],
  function ($m){
    $today_date = Carbon::now()->addDays(60);
    foreach ($emails as $key3 => $value) {
       $filiale = Filiale::where('adm_email', json_encode($value))
            ->select('filiales.id_filiale')
            ->value('filiales.id_filiale');  
      
       $contras = Projet_Casting::join('contrats','contrats.id_contrat','=','projets_castings.id_contrat')
            ->leftjoin('projets','projets.id_projet','=','projets_castings.id_projet')
            ->join('castings','castings.id_casting','=','contrats.id_casting')
            ->where('contrats.actif',1)
            ->where('contrats.date_fin_contrat', '<=', $today_date)
            ->where('projets.id_filiale',$filiale)
            ->get();

       foreach($value as $val =>$v){
          $m->to($v,'Notify')->subject('Contrats à renouveler')->setBody($contras);
       }
    }  
 });

所有逻辑写在同一个Mail::send的闭包内,全程复用同一个邮件实例$m,每次调用to()和setBody()都会覆盖之前的设置,最终所有收件人收到的都是最后一次设置的内容。

第二版代码问题

$today_date = Carbon::now()->addDays(60);
$contrat_email = Projet_Casting::join('contrats','contrats.id_contrat','=','projets_castings.id_contrat')->leftjoin('projets','projets.id_projet','=','projets_castings.id_projet')->join('castings','castings.id_casting','=','contrats.id_casting')->join('filiales','projets.id_filiale','=','filiales.id_filiale')->where('contrats.actif',1)->where('contrats.date_fin_contrat', '<=', $today_date)->distinct('filiales.id_filiale')->get();
$emails = array();
foreach($contrat_email as $key) {
  $emails[] = json_decode($key->adm_email);
}
$email_send = array();
foreach ($emails as $key3 => $value) {
  $filiale =Filiale::where('adm_email', json_encode($value))->select('filiales.id_filiale')->value('filiales.id_filiale');
  $contras = Projet_Casting::join('contrats','contrats.id_contrat','=','projets_castings.id_contrat')->leftjoin('projets','projets.id_projet','=','projets_castings.id_projet')->join('castings','castings.id_casting','=','contrats.id_casting')->where('contrats.actif',1)->where('contrats.date_fin_contrat', '<=', $today_date)->where('projets.id_filiale',$filiale)->get();
  foreach($value as $val =>$v){          
    $ema = $v;
  }
  Mail::send([],[],
  function ($m){
    $m->to($ema,'Notify')->subject('Contrats à renouveler')->setBody($contras);
  }); 
}
  • 闭包作用域问题:PHP匿名函数默认无法直接访问外部变量,没有用use将$ema和$contras传入闭包,所以报Undefined variable: ema错误。
  • 邮箱赋值逻辑错误:遍历邮箱数组时只把最后一个邮箱赋值给$ema,同一个分公司下的多个邮箱只有最后一个能收到邮件。
  • 冗余查询:已经从$contrat_email中拿到了分公司数据,不需要再次查询id_filiale。

修复后的实现代码

$today_date = Carbon::now()->addDays(60);
// 先查出所有有待续约合同的分公司
$filiales = Filiale::whereHas('projets.contrats', function ($query) use ($today_date) {
    $query->where('actif', 1)
          ->where('date_fin_contrat', '<=', $today_date);
})->get();

foreach ($filiales as $filiale) {
    // 解析当前分公司的管理员邮箱列表
    $emails = json_decode($filiale->adm_email, true);
    // 查询当前分公司对应的待续约合同
    $contras = Projet_Casting::join('contrats','contrats.id_contrat','=','projets_castings.id_contrat')
        ->leftjoin('projets','projets.id_projet','=','projets_castings.id_projet')
        ->join('castings','castings.id_casting','=','contrats.id_casting')
        ->where('contrats.actif',1)
        ->where('contrats.date_fin_contrat', '<=', $today_date)
        ->where('projets.id_filiale', $filiale->id_filiale)
        ->get();
    
    // 给每个管理员单独发送对应内容的邮件
    foreach ($emails as $email) {
        Mail::send([], [], function ($m) use ($email, $contras) {
            // 注意:setBody不能直接传入集合对象,需要转成字符串/HTML/JSON,正式使用建议渲染邮件视图
            $m->to($email, 'Notify')
              ->subject('Contrats à renouveler')
              ->setBody($contras->toJson());
        });
    }
}

补充说明:如果需要发送格式化的合同内容,建议创建专属的邮件视图,把合同数据传入视图渲染后再作为邮件内容,可读性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 02:09:04