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

如何将数据库数据传递到Mailable?DB::select应放在控制器还是Mailable?

向Mailable传递数据的实现方式

你可以通过Mailable的构造函数接收外部传入的数据,只要将数据赋值给Mailable的公共属性,该属性会自动暴露给对应的邮件模板,不需要额外调用with方法传递。


DB查询的放置位置建议

优先把DB::select查询逻辑放在Controller层(更规范的实现是抽离到独立的Service/Repository层),不要放在Mailable中,原因如下:

  • 符合单一职责原则:Mailable的定位是负责邮件格式、内容渲染的封装,不应该承担数据查询的业务逻辑
  • 复用性更强:相同的查询逻辑如果其他业务需要调用,可以直接复用,不需要重复编写
  • 队列兼容性更好:如果你的Mailable开启了异步队列,放在构造函数中的查询会在任务推入队列时执行,如果队列有延迟发送的配置,查询到的数据可能和实际发送时的最新数据不一致;同时查询逻辑放在Controller中如果出错会直接在请求阶段抛出,更方便排查问题

现有代码修正

你现有代码存在两个明显问题:

  1. Controller中引用的是ContactMail类,但你的Mailable类名是TestMail,属于笔误会报错
  2. TestMail的build方法中调用with('data', $data)的$data未声明,需要加$this->才能读取类的属性

修正后TestMailController.php代码

<?php

namespace App\Http\Controllers;

use App\Mail\TestMail;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\DB;

class TestMailController extends Controller
{
    public function test()
    {
        // 数据查询放在Controller层
        $data = DB::select('select * from db_name');
        // 把查询结果传入Mailable构造
        return new TestMail($data);
    }
}

修正后TestMail.php代码

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class TestMail extends Mailable implements ShouldQueue
{
    use Queueable, SerializesModels;

    // 公共属性,会自动传递给邮件模板
    public $data;

    // 接收外部传入的数据
    public function __construct($data)
    {
        $this->data = $data;
    }

    public function build()
    {
        // 公共属性已经自动传给模板,不需要再写with,如果你需要自定义变量名也可以加with
        return $this->markdown('emails.testmail');
    }
}

内容的提问来源于stack exchange,提问作者Artur Müller Romanov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 16:24:03