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

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));
});

总结

  1. 控制器必须返回JsonResponse或标准响应对象,不能返回邮件对象;
  2. $context保持一维关联数组,直接传递给->context();
  3. 确保模板变量名与$context键名一致;
  4. 验证AJAX请求的数据格式和CSRF令牌。

按照以上步骤调整后,即可解决报错并正常发送邮件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 00:57:24