Symfony邮件发送报错:WrappedTemplatedEmail无法转为字符串
问题排查与解决方案
核心错误原因
你遇到的 Object of class Symfony\Bridge\Twig\Mime\WrappedTemplatedEmail could not be converted to string 报错,本质是控制器方法返回了邮件对象而非AJAX所需的响应格式。Symfony会尝试将返回值转为字符串输出,而WrappedTemplatedEmail对象无法直接转成字符串,因此触发错误。
分步排查与解决
1. 修正控制器返回值
确保AJAX对应的控制器方法最后返回JsonResponse或Response对象,而非直接返回邮件服务生成的Email对象。
错误示例(触发报错):
public function sendEmail(...) { $email = $this->mailService->send(...); $mailer->send($email); return $email; // 错误:返回了邮件对象 }
正确示例:
use Symfony\Component\HttpFoundation\JsonResponse; public function sendEmail(Request $request, SendMailService $mailService, MailerInterface $mailer): JsonResponse { // 处理请求数据、构建context... $email = $mailService->sendEmail($emailTo, $context); $mailer->send($email); // 返回AJAX需要的JSON响应 return new JsonResponse(['status' => 'success', 'message' => '邮件发送成功'], 200); }
2. 确保$context为关联数组
你提到将->context($context)改为->context([$context])后模板找不到prenom,这是因为后者把原关联数组包成了二维数组,模板中需要用{{ context.prenom }}才能访问,但你的模板写法是直接用{{ prenom }},所以变量找不到。
正确的$context应该是一维关联数组,包含模板所需的所有键值对:
// 控制器中构建context $context = [ 'prenom' => $request->request->get('prenom'), // 其他模板需要的变量,比如邮件内容、链接等 ]; // 服务类中直接传递该数组 public function sendEmail(string $to, array $context): WrappedTemplatedEmail { return (new TemplatedEmail()) ->to($to) ->from('noreply@yourdomain.com') ->subject('你的邮件主题') ->htmlTemplate('emails/your-template.html.twig') ->context($context); // 直接传一维关联数组,不要嵌套 }
3. 验证Twig模板变量
确保Twig模板中使用的变量名与$context中的键完全一致,比如模板中写{{ prenom }},则$context必须包含'prenom'键。
示例模板片段:
{# templates/emails/your-template.html.twig #} <h1>Bonjour {{ prenom }} !</h1> <p>这是测试邮件内容...</p>
4. 检查AJAX请求数据
确保AJAX提交的数据正确传递到控制器:
- 如果是JSON格式提交,需设置
Content-Type: application/json,并在控制器中用json_decode($request->getContent(), true)解析; - 如果是表单数据提交,用
$request->request->get('字段名')获取值; - 不要遗漏CSRF令牌(Symfony默认开启CSRF保护,AJAX请求需在headers中携带
X-CSRF-Token)。
示例AJAX代码:
document.getElementById('send-email-btn').addEventListener('click', function() { fetch('/send-email', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content }, body: JSON.stringify({ emailTo: document.getElementById('emailTo').value, prenom: document.getElementById('prenom').value }) }) .then(res => res.json()) .then(data => console.log(data)) .catch(err => console.error(err)); });
总结
- 控制器必须返回
JsonResponse或标准响应对象,不能返回邮件对象; $context保持一维关联数组,直接传递给->context();- 确保模板变量名与
$context键名一致; - 验证AJAX请求的数据格式和CSRF令牌。
按照以上步骤调整后,即可解决报错并正常发送邮件。
内容的提问来源于stack exchange,提问作者Na Ba
相关产品推荐
相关产品推荐

