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

如何在Laravel中执行更新同时获取数据并用于foreach循环发邮件?

问题分析

你当前的代码存在两个核心问题:

  • update()方法执行后返回的是受影响的行数(整数类型),而非查询构建器实例,所以后续调用get()会直接抛出错误,这也是你无法拿到数据用于循环的根本原因。
  • 你在foreach中使用的$encomendasnaopagas变量并未在代码中定义,这会触发「变量未定义」的运行时错误。
解决方案

要实现「更新数据同时获取目标数据用于发邮件」,正确的思路是先获取符合条件的记录,再批量更新状态,最后循环这些记录发送邮件。如果需要确保更新和发邮件操作的原子性(比如更新失败就不发送邮件),还可以用数据库事务包裹整个流程。

修正后的基础代码示例

// 1. 先获取所有需要更新的记录,包含关联的distritos数据
$encomendasParaAtualizar = encomendas::where('estado', 3)
    ->where('updated_at', '<', $dias2)
    ->join('distritos', 'encomendas.distrito', '=', 'distritos.id')
    ->get();

// 2. 批量更新这些记录的estado为4(先判断记录是否为空,避免无意义的数据库操作)
if ($encomendasParaAtualizar->isNotEmpty()) {
    encomendas::whereIn('id', $encomendasParaAtualizar->pluck('id'))
        ->update(['estado' => 4]);
}

// 3. 循环获取到的记录发送邮件
foreach ($encomendasParaAtualizar as $encomenda) {
    Mail::send('emails.cliente.cancelada', [
        'id_encomenda' => $encomenda->id,
        // 如果需要使用distritos表的字段,可直接调用,比如$encomenda->distrito->nome(前提是模型已定义关联)
    ], function ($messagem) use ($encomenda) {
        $messagem->from('noreply@cccc.pt', 'xxx');
        $messagem->to($encomenda->email)->subject('xxxxx');
    });
}

进阶:加入事务保障(可选)

如果希望更新操作和发邮件操作「要么全部成功,要么全部回滚」(避免出现数据更新了但邮件没发、或者邮件发了但数据没更新的不一致情况),可以用Laravel的数据库事务包裹:

use Illuminate\Support\Facades\DB;

try {
    DB::beginTransaction();

    $encomendasParaAtualizar = encomendas::where('estado', 3)
        ->where('updated_at', '<', $dias2)
        ->join('distritos', 'encomendas.distrito', '=', 'distritos.id')
        ->get();

    if ($encomendasParaAtualizar->isNotEmpty()) {
        encomendas::whereIn('id', $encomendasParaAtualizar->pluck('id'))
            ->update(['estado' => 4]);
    }

    foreach ($encomendasParaAtualizar as $encomenda) {
        Mail::send('emails.cliente.cancelada', [
            'id_encomenda' => $encomenda->id,
        ], function ($messagem) use ($encomenda) {
            $messagem->from('noreply@cccc.pt', 'xxx');
            $messagem->to($encomenda->email)->subject('xxxxx');
        });
    }

    DB::commit();
} catch (\Exception $e) {
    DB::rollBack();
    // 这里可以添加异常处理逻辑,比如记录错误日志:Log::error($e->getMessage());
}

额外提示

  • 建议在encomendas模型中定义与distritos的关联关系(比如belongsTo),这样后续访问关联表字段会更符合Laravel的Eloquent风格,也可以省略join语句。
  • 如果需要处理大量邮件,推荐使用Laravel的队列异步发送邮件,避免同步发送导致请求超时。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 07:02:40