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

Yii2配置SMTP发送密码重置邮件失败 表单报错求助

Yii2忘记密码邮件功能报错排查

问题背景

需要实现忘记密码流程:用户提交注册邮箱后,系统向该邮箱发送重置密码链接,用户点击链接即可跳转设置新密码。目前参考官方文档完成了基础配置,但提交表单时控制台报ActiveForm相关错误,无法定位问题根源。

现有配置与代码

mailer组件配置

'mailer' => [
    'class' => 'yii\swiftmailer\Mailer',
    'htmlLayout' =>  '@app/mail/layouts/html',
    // 'viewPath' => '@common/mail',
    // 'useFileTransport' => true,
    'transport' => [
        'class' => 'Swift_SmtpTransport',
        'host' => 'smtp.gmail.com',
        'username' => 'username',
        'password' => 'app_password',
        'port' => '587',
        'encryption' => 'ssl',
    ],
    'streamOptions' => [ 
        'ssl' => [ 
            'allow_self_signed' => true,                         
            'verify_peer' => false,                         
            'verify_peer_name' => false,                     
        ],
    ],
]

控制器actionForgot代码

public function actionForgot()
{
    if(isset($_POST['Lupa']))
    {
        $getEmail=$_POST['Lupa']['email'];
        $getModel= Users::findOne(['email' => $getEmail]);
        $getToken=rand(0, 99999);
        $getTime=date("H:i:s");
        // $getModel->token=md5($getToken.$getTime);
        $org="Some Team";
        $emailadmin="admin_email";
        $subjek="Reset Password";
        $setpesan="you have successfully reset your password<br/>
            <a href='http://localhost:8080/site/forgot?r=site/vertoken/view&token='>Click Here to Reset Password</a>";
        
        if(!$getModel) {
            Yii::$app->session->setFlash('error', 'Please fill in an registered email');
        }
        else if($getModel->validate())
            {
                $name='=?UTF-8?B?'.base64_encode($org).'?=';
                $subject='=?UTF-8?B?'.base64_encode($subjek).'?=';
                $headers="From: $name <{$emailadmin}>\r\n".
                    "Reply-To: {$model->email}\r\n".
                    "MIME-Version: 1.0\r\n".
                    "Content-type: text/html; charset=UTF-8";
                $getModel->save();
                Yii::app()->user->setFlash('forgot','link to reset your password has been sent to your email');
                mail($getEmail,$subject,$setpesan,$headers);
                Yii::$app->mailer->compose()
                    ->setFrom($emailadmin)
                    ->setTo($getEmail)
                    ->setSubject($subjek)
                    ->send();
                $this->refresh();
            }
    }
    $this->layout = 'forgot';
    return $this->render('forgot');
}

触发报错的视图代码

<?php $form = ActiveForm::begin([
    'id' => 'forgot-form',
    'enableClientValidation'=>false,
    'validateOnSubmit' => true, 
]); ?>

问题根因

控制台报ActiveForm相关错误是表象,本质是后端PHP代码运行抛出致命错误,导致AJAX验证请求返回500状态码,前端JS无法解析返回结果才报错,具体代码问题如下:

  • SMTP配置错误:Gmail SMTP的587端口对应加密协议为tls,465端口才对应ssl,当前配置端口和加密协议不匹配,会直接导致SMTP连接失败。另外streamOptions配置位置错误,该参数需要放在transport节点下,和host、port等参数同级,当前放在外层不会生效。同时配置中没有明确设置useFileTransport => false,部分环境下默认会开启写文件模式,不会真实发信。
  • 混用Yii1和Yii2语法:Yii::app()->user->setFlash()是Yii1框架的写法,Yii2中全局实例统一通过Yii::$app调用,运行到该行会直接抛出类不存在的致命错误。
  • 未定义变量:组装邮件头时调用了$model->email,但上下文中查询得到的用户对象变量名为$getModel,不存在$model变量,会触发未定义变量错误。
  • 重复发信逻辑:同时调用了PHP原生mail()函数和Yii mailer组件的send()方法,两套逻辑冗余,且原生mail()函数未配置SMTP的情况下无法正常发信,会额外抛出错误。
  • 业务逻辑缺失:生成的重置密码token被注释,没有赋值给用户模型存储,邮件内的重置链接也没有拼接token参数,就算邮件发送成功,用户也无法完成密码重置。同时调用$getModel->save()时没有判断返回值,模型保存失败时仍会继续执行后续发信逻辑。
  • 邮件内容为空:调用compose()方法时没有传入邮件视图或正文内容,提前写好的$setpesan正文没有被传入,最终发出的邮件是空白内容。
  • 请求参数获取不规范:直接读取$_POST['Lupa']获取表单参数,没有通过Yii提供的Yii::$app->request->post()方法获取,也没有绑定对应表单模型,参数名不匹配时会直接进入不了提交逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 14:03:27