October CMS 按钮发送模型字段读取的邮箱邮件报错问题
问题原因
代码存在两处核心错误,直接导致邮箱读取失败、发信报错:
- 模型取值逻辑错误:
Machines::get('email')是全局查询所有Machines表记录的email字段,返回的是多维集合对象,根本不是当前操作的单条记录对应的邮箱值。 - 闭包作用域绑定错误:
Mail::send的闭包默认绑定到邮件消息实例,并非当前控制器对象,在闭包内调用$this->vars完全读不到控制器上赋值的变量。另外$this->vars是给视图模板传参用的属性,在控制器内部逻辑里不需要绕这一层存值。
修正方案
场景1:按钮放在Machines模型的后台表单编辑页
如果按钮是放在单条Machine记录的编辑表单里,控制器直接调用框架内置的formGetModel()方法就能拿到当前绑定的模型实例,替换控制器的onSend方法代码如下:
public function onSend() { // 获取当前表单绑定的单条Machines记录 $machine = $this->formGetModel(); $targetEmail = trim($machine->email); // 提前校验邮箱避免无效发信 if (empty($targetEmail) || !filter_var($targetEmail, FILTER_VALIDATE_EMAIL)) { throw new \ApplicationException("当前记录未配置有效邮箱地址,无法发送提醒"); } // 通过use关键字把邮箱变量传入闭包作用域 Mail::send('martin.maintenance::mail.maintenancereminder', [], function($message) use ($targetEmail) { $message->to($targetEmail); }); // 可选:发信成功后返回前端提示 return [ '#flashMessages' => $this->makePartial('flash', [ 'type' => 'success', 'content' => '提醒邮件已发送至:' . $targetEmail ]) ]; }
现有的模型字段配置、按钮代码不需要改动,替换完控制器代码即可正常运行。
场景2:按钮放在列表页/前端公共页面
如果按钮不是放在单条记录的编辑表单里,需要先给按钮加请求参数,传递当前要操作的记录ID,修改按钮代码:
<button type="submit" data-request="onSend" data-request-data="machineId: {{ $record->id }}" class="btn btn-primary"> Reminder </button>
对应的控制器方法改成根据传入ID查询目标记录:
public function onSend() { $machineId = post('machineId'); $machine = Machines::findOrFail($machineId); $targetEmail = trim($machine->email); if (empty($targetEmail) || !filter_var($targetEmail, FILTER_VALIDATE_EMAIL)) { throw new \ApplicationException("当前记录未配置有效邮箱地址,无法发送提醒"); } Mail::send('martin.maintenance::mail.maintenancereminder', [], function($message) use ($targetEmail) { $message->to($targetEmail); }); }
补充说明
提供的Machines模型yaml字段配置没有问题,text类型字段完全支持存储邮箱格式的字符串,不需要额外调整。
内容的提问来源于stack exchange,提问作者MartinJuniorS
相关产品推荐
相关产品推荐

