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

CodeIgniter中数据库数据获取异常及邮件发送失败问题求助

解决CodeIgniter预约确认邮件发送问题

看起来你遇到了几个核心问题,导致邮件无法发送还出现了非对象的PHP提示,咱们一步步来解决:

1. 修复模型的查询逻辑(解决非对象错误)

你的App_model里的send_mail方法没有接收$appointment_id参数,所以它会返回所有预约记录,而不是你指定ID的那一条。当你在控制器里尝试访问$appointment[0]->cust_name时,如果查询结果为空(或者没有匹配的ID),$appointment[0]就不是对象,自然会触发那个Notice错误。

修改App_model.php的send_mail方法,添加参数和WHERE条件:

public function send_mail($appointment_id) { 
    $query=$this->db 
        ->select('*, employee.name_emp as emp_name, customer.name as cust_name, customer.email as cust_email, servicetype.name_set as s_name, serviceplan.price as p_rice') 
        ->from('appointment') 
        ->join('customer', 'customer.id= appointment.name_app') 
        ->join('servicetype', 'servicetype.id_set= appointment.sertype') 
        ->join('employee', 'employee.id_emp= appointment.emp') 
        ->join('serviceplan', 'serviceplan.price=appointment.price_app') // 取消注释,关联服务价格表
        ->where('appointment.id', $appointment_id) // 关键:筛选指定ID的预约
        ->get(); 
    return $query->row(); // 用row()返回单条记录,无需用数组索引访问
}

这里用row()代替result(),因为我们只需要一条预约记录,后续在控制器里可以直接通过对象属性访问数据,不用再取数组下标。

2. 修复控制器的邮件内容与逻辑(解决邮件无法发送)

你直接把数组$message传给了$this->email->message(),但CodeIgniter的邮件类需要的是字符串(HTML或纯文本),不是数组。另外,还要先判断查询结果是否存在,避免再次触发非对象错误。

修改App_controller.php的sendmail方法:

function sendmail($appointment_id){ 
    $config = Array( 
        'protocol' => 'smtp', 
        'smtp_host' => 'ssl://smtp.googlemail.com', 
        'smtp_port' => 465, 
        'smtp_user' => '你的谷歌邮箱地址', 
        'smtp_pass' => '你的谷歌应用专用密码', // 注意:不能用普通账号密码,后续说明
        'mailtype' => 'html', 
        'charset' => 'utf-8' // 替换为utf-8避免乱码
    ); 

    $this->load->library('email', $config); 
    $this->email->set_newline("\r\n"); 

    $this->load->model('App_model'); 
    $appointment = $this->App_model->send_mail($appointment_id); 

    // 先判断是否获取到有效预约数据
    if(!$appointment){
        echo "找不到对应的预约记录,请检查ID是否正确";
        return;
    }

    // 构建HTML格式的邮件内容
    $message = '<h2>预约确认通知</h2>';
    $message .= '<p>尊敬的 '.$appointment->cust_name.':</p>';
    $message .= '<p>您的预约已成功提交,以下是预约详情:</p>';
    $message .= '<ul>';
    $message .= '<li>服务类型:'.$appointment->s_name.'</li>';
    $message .= '<li>服务员工:'.$appointment->emp_name.'</li>';
    $message .= '<li>预约日期:'.$appointment->date.'</li>';
    $message .= '<li>预约时间:'.$appointment->time.'</li>';
    $message .= '<li>服务价格:'.$appointment->p_rice.'</li>';
    $message .= '</ul>';
    $message .= '<p>感谢您的信任,我们期待为您服务!</p>';

    $this->email->from('你的邮箱地址', '你的店铺/品牌名称'); 
    $this->email->to($appointment->cust_email); // 发送给客户的真实邮箱
    $this->email->subject('Your Appointment Confirmation'); 
    $this->email->message($message); 

    // 添加调试输出,快速定位发送失败原因
    if(!$this->email->send()){
        echo "<h3>邮件发送失败,错误信息:</h3>";
        echo $this->email->print_debugger();
    } else {
        echo "预约确认邮件已成功发送给客户!";
    }
}

注意几个关键修正:

  • 将收件人从固定的xxx改为从数据库获取的客户邮箱$appointment->cust_email
  • 把邮件内容改为HTML字符串,符合mailtype => html的配置要求
  • 添加了数据存在性判断,避免空对象报错
  • 增加了调试输出,方便排查SMTP连接或邮件内容的问题

3. 修复谷歌SMTP的权限问题

现在谷歌邮箱默认禁止使用普通账号密码通过SMTP发送邮件,你需要完成以下两步:

  1. 开启谷歌账号的两步验证
  2. 生成一个应用专用密码(App Password),用这个密码替换配置里的smtp_pass
    如果跳过这一步,SMTP连接会直接失败,邮件无法发送。

4. 额外调试建议

如果还是有问题,可以开启CodeIgniter的调试模式查看详细错误:
在application/config/config.php中设置:

$config['debug'] = true;

另外,$this->email->print_debugger()会输出SMTP连接的完整日志,包括连接状态、错误代码等,这是排查邮件发送问题的核心工具。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:42:02