首页 > 解决方案 > 为什么在此 Codeigniter 3 应用程序中通过电子邮件发送密码重置链接失败?

问题描述

我正在使用 Codeigniter 3.1.8 和 Bootstrap 4 开发一个基本的博客应用程序

我在这个应用程序中添加了一个注册和登录系统。

我在开发密码重置功能时遇到了这个问题:包含重置链接的电子邮件未发送(或可能未收到)。

密码重置表格采用注册时使用的电子邮件地址:

<?php echo form_open(base_url('newpassword')); ?>
  <div class="form-group <?php if(form_error('email')) echo 'has-error';?>">
    <input type="text" name="email" id="email" class="form-control" placeholder="Email">
    <?php if(form_error('email')) echo form_error('email'); ?> 
  </div>

  <div class="form-group mb-2">
    <input type="submit" value="Reset password" class="btn btn-block btn-md btn-success">
  </div>            
<?php echo form_close(); ?>

控制器:

class Newpassword extends CI_Controller {
    public function __construct()
    {
        parent::__construct();
    }

    private $headers = '';
    private $user_email = '';
    private $subject = 'Pasword reset link';
    private $reset_link = '<a href="#">Dummy Reset Link</a>';
    private $body = '';

    public function index() {
        // Display form
        $data = $this->Static_model->get_static_data();
        $data['pages'] = $this->Pages_model->get_pages();
        $data['tagline'] = 'Reset your password';
        $data['categories'] = $this->Categories_model->get_categories();

        // Form validation rules
        $this->form_validation->set_rules('email', 'Email', 'required|trim|valid_email');
        $this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');

        if(!$this->form_validation->run()) {
            $this->load->view('partials/header', $data);
            $this->load->view('auth/passwordreset');
            $this->load->view('partials/footer');
        } else {
            if ($this->Usermodel->email_exists()) {
                $this->user_email = $this->input->post('email');
                $this->body = "Your password reset link: $this->reset_link\n\nAfter clicking it you will be redirected to a page on the website where you will be able to set a new pasword.";
                $this->headers = "From: noreply@yourdomain.com\n";

                // Send mail and rediect
                $this->sendResetMail();             
            } else {
                $this->session->set_flashdata('email_non_existent', "The email you provided does not exist in our database");
            }
           redirect('newpassword');
        }
    }

    public function sendResetMail() {
        if (mail($this->user_email, $this->subject, $this->body, $this->headers)) {
            $this->session->set_flashdata('reset_mail_confirm', "A pasword reset link was send to the email address $this->user_email");
        } else {
            $this->session->set_flashdata('reset_mail_fail', "Our atempt to send a pasword reset link to $this->user_email has failed");
        }
    }
}

检查电子邮件是否存在的方法(也用于注册,它有效):

public function email_exists() {    
    $query = $this->db->get_where('authors', ['email' => $this->input->post('email')]);
    return $query->num_rows() > 0;
}

虽然我收到确认电子邮件已发送的 Flash 消息,但我实际上并没有收到电子邮件。

我的赌注在哪里?

标签: phpcodeignitercodeigniter-3

解决方案


我修改了您的课程以使用内置的电子邮件库,并将我的代码从一个工作项目中混合:

class Newpassword extends CI_Controller {
    public function __construct()
    {
        parent::__construct();
    }

    // Sender email
    private $my_email = "example@example.com";
    // Sender name
    private $my_name = "Example";
    

    private $user_email = '';
    private $subject = 'Pasword reset link';
    private $reset_link = '<a href="#">Dummy Reset Link</a>';
    private $body = '';

    public function index() {
        // Display form
        $data = $this->Static_model->get_static_data();
        $data['pages'] = $this->Pages_model->get_pages();
        $data['tagline'] = 'Reset your password';
        $data['categories'] = $this->Categories_model->get_categories();

        // Form validation rules
        $this->form_validation->set_rules('email', 'Email', 'required|trim|valid_email');
        $this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');

        if(!$this->form_validation->run()) {
            $this->load->view('partials/header', $data);
            $this->load->view('auth/passwordreset');
            $this->load->view('partials/footer');
        } else {
            if ($this->Usermodel->email_exists()) {
                $this->user_email = $this->input->post('email');
                $this->body = "Your password reset link: $this->reset_link\n\nAfter clicking it you will be redirected to a page on the website where you will be able to set a new pasword.";

                // Send mail and rediect
                $this->sendResetMail();             
            } else {
                $this->session->set_flashdata('email_non_existent', "The email you provided does not exist in our database");
            }
           redirect('newpassword');
        }
    }

    public function sendResetMail() {
        // Loading the Email library
        $config['protocol'] = 'sendmail';
        $config['charset'] = 'utf-8';
        $config['mailtype'] = 'html';

        if($this->load->is_loaded('email')){
            $this->email->initialize($config);
        }
        else{
            $this->load->library('email',$config);
        }

        // Build the body and meta data of the email message
        $this->email->from($this->my_email,$this->my_name);
        $this->email->to($this->user_email);
        $this->email->subject($this->subject);
        
        $this->email->message($this->body);

        if($this->email->send()){
            $this->session->set_flashdata('reset_mail_confirm', "A pasword reset link was send to the email address $this->user_email");
        }else{
            $this->session->set_flashdata('reset_mail_fail', "Our atempt to send a pasword reset link to $this->user_email has failed");
        }
    }
}

推荐阅读