PHP项目Symfony form与抄送通知

wen PHP项目 1

本文目录导读:

PHP项目Symfony form与抄送通知

  1. 创建表单类型
  2. 控制器处理表单与发送通知
  3. 邮件模板
  4. 邮件配置(.env)
  5. 增强功能:可配置抄送名单
  6. 使用事件监听器自动处理
  7. 最佳实践建议

在Symfony项目中处理表单与抄送通知,通常涉及以下几个核心环节:

创建表单类型

// src/Form/ContactType.php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
class ContactType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('name', TextType::class, [
                'label' => '姓名',
                'attr' => ['class' => 'form-control']
            ])
            ->add('email', EmailType::class, [
                'label' => '邮箱',
                'attr' => ['class' => 'form-control']
            ])
            ->add('message', TextareaType::class, [
                'label' => '留言内容',
                'attr' => ['class' => 'form-control', 'rows' => 5]
            ])
            ->add('submit', SubmitType::class, [
                'label' => '提交',
                'attr' => ['class' => 'btn btn-primary']
            ]);
    }
    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => null, // 或者映射到实体类
        ]);
    }
}

控制器处理表单与发送通知

// src/Controller/ContactController.php
namespace App\Controller;
use App\Form\ContactType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
use Symfony\Component\Routing\Annotation\Route;
class ContactController extends AbstractController
{
    #[Route('/contact', name: 'contact')]
    public function index(Request $request, MailerInterface $mailer): Response
    {
        $form = $this->createForm(ContactType::class);
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $data = $form->getData();
            // 发送主通知给网站管理员
            $adminEmail = (new Email())
                ->from($data['email'])
                ->to('admin@example.com')
                ->subject('新的联系表单提交')
                ->html($this->renderView('emails/admin_notification.html.twig', [
                    'name' => $data['name'],
                    'email' => $data['email'],
                    'message' => $data['message']
                ]));
            $mailer->send($adminEmail);
            // 发送抄送给发件人(CC)
            $ccEmail = (new Email())
                ->from('noreply@example.com')
                ->to($data['email']) // 发送给发件人
                ->cc('manager@example.com') // 抄送给经理
                ->subject('感谢您的联系')
                ->html($this->renderView('emails/thank_you.html.twig', [
                    'name' => $data['name']
                ]));
            $mailer->send($ccEmail);
            // 多重抄送示例
            $this->sendWithMultipleCC($mailer, $data);
            $this->addFlash('success', '消息已发送成功!');
            return $this->redirectToRoute('contact');
        }
        return $this->render('contact/index.html.twig', [
            'form' => $form->createView(),
        ]);
    }
    private function sendWithMultipleCC(MailerInterface $mailer, array $data): void
    {
        $email = (new Email())
            ->from('noreply@example.com')
            ->to('support@example.com')
            ->subject('客户咨询')
            ->html($this->renderView('emails/customer_inquiry.html.twig', [
                'name' => $data['name'],
                'message' => $data['message']
            ]))
            ->cc([
                'sales@example.com',      // 抄送销售
                'manager@example.com',     // 抄送经理
                'crm@example.com'         // 抄送CRM系统
            ]);
        $mailer->send($email);
    }
}

邮件模板

{# templates/emails/admin_notification.html.twig #}
<!DOCTYPE html>
<html>
<head>新的联系表单提交</title>
</head>
<body>
    <h2>新的客户咨询</h2>
    <p><strong>姓名:</strong>{{ name }}</p>
    <p><strong>邮箱:</strong>{{ email }}</p>
    <p><strong>消息内容:</strong></p>
    <p>{{ message }}</p>
</body>
</html>
{# templates/emails/thank_you.html.twig #}
<!DOCTYPE html>
<html>
<head>感谢您的联系</title>
</head>
<body>
    <h2>亲爱的 {{ name }},</h2>
    <p>感谢您的联系!</p>
    <p>我们会在24小时内回复您的消息。</p>
</body>
</html>

邮件配置(.env)

# .env
MAILER_DSN=smtp://user:pass@smtp.example.com:587
# 如果需要使用Gmail
# MAILER_DSN=gmail://user:pass@default
# 开发环境使用 Mailpit 或 MailHog
# MAILER_DSN=smtp://localhost:1025

增强功能:可配置抄送名单

// src/Form/ContactType.php
public function buildForm(FormBuilderInterface $builder, array $options): void
{
    $builder
        // ... 其他字段
        ->add('cc_me', CheckboxType::class, [
            'label' => '发送副本给我',
            'required' => false,
            'attr' => ['class' => 'form-check-input']
        ]);
}
// 控制器中处理
if ($form->isSubmitted() && $form->isValid()) {
    $data = $form->getData();
    $email = (new Email())
        ->from('noreply@example.com')
        ->to('support@example.com')
        ->subject('客户咨询')
        ->html($this->renderView('emails/customer_inquiry.html.twig', $data));
    // 如果用户勾选了抄送选项
    if ($data['cc_me']) {
        $email->addCc($data['email']);
    }
    // 始终抄送经理
    $email->addCc('manager@example.com');
    // 抄送多个收件人
    $ccList = [
        'sales@example.com',
        'crm@example.com'
    ];
    $email->cc(...$ccList);
    $mailer->send($email);
}

使用事件监听器自动处理

// src/EventSubscriber/MailNotificationSubscriber.php
namespace App\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
class MailNotificationSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            FormEvents::POST_SUBMIT => 'onPostSubmit',
        ];
    }
    public function onPostSubmit(FormEvent $event): void
    {
        $form = $event->getForm();
        $data = $form->getData();
        // 在这里处理邮件发送逻辑
    }
}

最佳实践建议

  1. 使用队列处理:对于大量邮件,使用Symfony Messenger异步处理
  2. 邮件模板化:使用Twig模板保持邮件格式统一
  3. 错误处理:添加try-catch块处理邮件发送失败
  4. 日志记录:记录邮件发送成功/失败状态
  5. 限制频率:防止表单滥用导致大量邮件发送

这样就能在Symfony表单提交后,灵活地处理主通知和抄送通知了。

抱歉,评论功能暂时关闭!