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

如何在CodeIgniter 4中通过表单将数据发送至指定邮箱

如何在CodeIgniter 4中实现表单数据发送到指定邮箱?

我查阅了CodeIgniter 4官方文档,找到如下邮件发送代码:

$email = \Config\Services::email();

$email->setFrom('your@example.com', 'Your Name');
$email->setTo('someone@example.com');
$email->setCC('another@another-example.com');
$email->setBCC('them@their-example.com');

$email->setSubject('Email Test');
$email->setMessage('Testing the email class.');

$email->send();

但网上多数教程都是SMTP域名邮箱的发送方案,我没有域名邮箱,仅有客户在平台创建的邮箱,需要将表单提交的数据发送至该邮箱。

我使用的表单代码如下:

<form action="<?= base_url() ?>/save" method="post" enctype="multipart/form-data">
    <div class="mb-3">
        <input type="text" name="name" class="form-control" id="InputForName" value="<?= set_value('user_name') ?>" placeholder="Nombre y apellidos">
    </div>
    <div class="mb-3">
        <input type="email" name="email" class="form-control" id="InputForEmail" value="<?= set_value('user_email') ?>" placeholder="Email">
    </div>
    <div class="buttonHolder">
        <button type="submit" class="btn btn-info text-center">Enviar</button>
    </div>
</form>

我尝试在保存表单数据到数据库的控制器中加入邮件发送代码,但始终跳转到else分支,推测存在错误或方法不当,控制器代码如下:

public function save()
{
    //include helper form
    helper(['form']);
    //set rules validation form
    $rules = [
        'name'          => 'required|min_length[3]|max_length[100]',
        'email'         => 'required|min_length[6]|max_length[100]|valid_email|is_unique[users.user_email]'
    ];

    if ($this->validate($rules)) {
        $model = new UserModel();
        $data = [
            'user_name'     => $this->request->getVar('name'),
            'user_email'    => $this->request->getVar('email')
        ];

        $email = \Config\Services::email();

        $email->setFrom($data['user_email'], $data['user_name']);
        $email->setTo('clientemail@email.com');
        /*$email->setCC('another@another-example.com');
        $email->setBCC('them@their-example.com');*/

        $email->setSubject('lorem ipsum '.$data['user_name'].' lorem ipsum');
        $email->setMessage($data['user_name'].' lorem ipsumlorem ipsumlorem ipsumlorem ipsumlorem ipsumlorem ipsum'.$data['user_email']);

        $email->send();

        $model->save($data);
        //return redirect()->back(); //misma pagina
        return redirect()->to('/{locale}/gracias');
    } else {
        return redirect()->back(); //misma pagina
    }
}

问题定位与解决方案

1. 先解决跳转至else分支的问题

跳转到else分支的核心原因是表单验证未通过,你可以通过以下步骤定位具体错误:

  • 修改控制器else分支代码,携带验证错误信息返回:
    return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
    
  • 在表单页面添加错误信息显示:
    <?php if(session()->has('errors')): ?>
        <div class="alert alert-danger">
            <?php foreach(session('errors') as $error): ?>
                <p><?= $error ?></p>
            <?php endforeach; ?>
        </div>
    <?php endif; ?>
    

常见的验证失败原因包括:邮箱已存在(is_unique规则触发)、姓名长度不足、邮箱格式错误等,根据提示修正即可。

2. 修正邮件发送逻辑

你当前的邮件发送存在两个关键问题:

  • 用用户提交的邮箱作为发件人:多数服务器会拦截非本地域名的发件地址,导致邮件发送失败或被标记为垃圾邮件。
  • 未处理邮件发送失败的情况:即使验证通过,邮件发送失败也会影响流程。
解决方案:
  1. 配置合法的发件渠道
    编辑app/Config/Email.php,可以选择两种方案:

    • 方案一:使用服务器内置邮件功能(需服务器支持mail()函数)
      public $protocol = 'mail';
      public $mailPath = '/usr/sbin/sendmail'; // 根据服务器实际路径调整
      
    • 方案二:使用第三方免费SMTP服务(如163、QQ邮箱,无需域名)
      public $protocol = 'smtp';
      public $SMTPHost = 'smtp.163.com';
      public $SMTPUser = '你的163邮箱@163.com';
      public $SMTPPass = '邮箱授权码'; // 不是登录密码,需在邮箱后台开启SMTP并获取
      public $SMTPPort = 465;
      public $SMTPCrypto = 'ssl';
      
  2. 调整邮件发送代码
    使用配置的合法发件人,同时设置回复地址为用户邮箱,添加错误处理:

    $email = \Config\Services::email();
    // 使用配置的发件邮箱
    $email->setFrom('你的发件邮箱@xxx.com', '表单提交通知');
    $email->setTo('clientemail@email.com');
    // 设置用户邮箱为回复地址,方便客户直接回复
    $email->setReplyTo($data['user_email'], $data['user_name']);
    $email->setSubject('新表单提交:'.$data['user_name']);
    // 整理清晰的邮件内容
    $email->setMessage("用户姓名:{$data['user_name']}\n用户邮箱:{$data['user_email']}\n提交时间:".date('Y-m-d H:i:s'));
    
    // 检查邮件是否发送成功
    if (!$email->send()) {
        // 记录错误日志,便于排查
        log_message('error', '邮件发送失败:'.$email->printDebugger(['headers', 'body']));
        // 返回错误提示给用户
        return redirect()->back()->withInput()->with('error', '提交失败,请稍后重试');
    }
    
  3. 完善表单页面的错误提示
    在表单中添加全局错误提示:

    <?php if(session()->has('error')): ?>
        <div class="alert alert-danger">
            <?= session('error') ?>
        </div>
    <?php endif; ?>
    

3. 最终完整控制器代码

public function save()
{
    helper(['form']);
    $rules = [
        'name'          => 'required|min_length[3]|max_length[100]',
        'email'         => 'required|min_length[6]|max_length[100]|valid_email|is_unique[users.user_email]'
    ];

    if ($this->validate($rules)) {
        $model = new UserModel();
        $data = [
            'user_name'     => $this->request->getVar('name'),
            'user_email'    => $this->request->getVar('email')
        ];

        $email = \Config\Services::email();
        $email->setFrom('你的发件邮箱@xxx.com', '表单提交通知');
        $email->setTo('clientemail@email.com');
        $email->setReplyTo($data['user_email'], $data['user_name']);
        $email->setSubject('新表单提交:'.$data['user_name']);
        $email->setMessage("用户姓名:{$data['user_name']}\n用户邮箱:{$data['user_email']}\n提交时间:".date('Y-m-d H:i:s'));

        if (!$email->send()) {
            log_message('error', '邮件发送失败:'.$email->printDebugger(['headers', 'body']));
            return redirect()->back()->withInput()->with('error', '提交失败,请稍后重试');
        }

        $model->save($data);
        return redirect()->to('/{locale}/gracias');
    } else {
        return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 18:31:07