CodeIgniter Email类默认不支持SMTP认证,必须显式配置protocol、smtp_host、smtp_port、smtp_user、smtp_pass、smtp_crypto等参数,且Gmail等需用应用专用密码;失败时须调用print_debugger()查看SMTP交互日志定位问题。

CodeIgniter 自带的 Email 类能发邮件,但默认不支持 SMTP 认证(如 Gmail、Outlook),直接调用 $this->email->send() 很可能返回 false 且无明确错误提示——问题通常出在协议配置或 PHP 环境限制,不是代码写错了。
SMTP 配置必须显式设置,不能依赖 php.ini 的 sendmail
本地开发或共享主机上,mail() 函数常被禁用或不可靠。CodeIgniter 默认走 mail 协议,但实际应强制走 smtp。关键配置项必须全部指定,漏掉 smtp_port 或 smtp_user 都会导致静默失败:
-
protocol必须设为'smtp'(字符串,不是smtp) -
smtp_host填服务商地址,例如 Gmail 是'smtp.gmail.com',腾讯企业邮箱是'smtp.exmail.qq.com' -
smtp_port注意:Gmail 要用587(TLS)或465(SSL),填错端口会卡住几秒后超时 -
smtp_user和smtp_pass是登录凭证;Gmail 必须用「应用专用密码」,不能用账号密码 -
smtp_crypto必须匹配端口:'tls'对应587,'ssl'对应465
示例配置(Gmail):
$config = [
'protocol' => 'smtp',
'smtp_host' => 'smtp.gmail.com',
'smtp_port' => 587,
'smtp_user' => 'your@gmail.com',
'smtp_pass' => 'your_app_password', // 不是登录密码
'smtp_crypto' => 'tls',
'mailtype' => 'html',
'charset' => 'utf-8',
'wordwrap' => TRUE
];
$this->email->initialize($config);
发送前务必检查 $this->email->print_debugger() 输出
CodeIgniter 的 Email 类不抛异常,失败时只返回 false。调试唯一可靠方式是调用 $this->email->print_debugger() ——它会输出原始 SMTP 交互日志,包括连接是否建立、认证是否通过、服务器返回的错误码(比如 535 Authentication Credentials Invalid)。
- 不要只看
if (!$this->email->send())就报“发送失败”,先打印调试信息 - 如果日志里出现
Connection refused,大概率是防火墙/主机屏蔽了 SMTP 端口,或smtp_host拼写错误 - 如果卡在
Authenticating...后无响应,检查smtp_crypto和smtp_port是否匹配
附件路径必须是服务器绝对路径,相对路径会静默丢弃
添加附件用 $this->email->attach(),但它只接受文件系统中的真实路径,不支持 URL 或 CodeIgniter 的资源别名(如 APPPATH 或 FCPATH 需要手动拼接)。
- 错误写法:
$this->email->attach('uploads/file.pdf')→ 会被忽略 - 正确写法:
$this->email->attach(FCPATH . 'uploads/file.pdf')(FCPATH是入口文件所在目录) - 如果附件不存在或权限不足,
send()仍返回true,但邮件里没附件——必须用file_exists()和is_readable()提前校验
中文收件人和主题需用 mb_encode_mimeheader() 编码
直接传中文到 to() 或 subject() 会导致乱码或被拒收。CodeIgniter 不自动处理 MIME 编码,需手动转义:
- 收件人姓名含中文:
$this->email->to('张三 <user@example.com>')→ 先对“张三”编码:mb_encode_mimeheader('张三', 'UTF-8', 'B', '\n') - 主题含中文:
$this->email->subject(mb_encode_mimeheader('订单通知', 'UTF-8', 'B')) - 注意:
mbstring扩展必须启用,否则函数不存在;测试时可用function_exists('mb_encode_mimeheader')安全校验
最易被忽略的是调试阶段依赖 print_debugger() ——它不光看有没有报错,更要逐行读 SMTP 响应码。很多问题表面是“发不出”,实则是 TLS 握手失败或证书验证被跳过(CodeIgniter 旧版本默认跳过,新版本需显式设 'smtp_verify_peer' => FALSE 才兼容自签名证书)。


















