Codeigniter发送ical事件到Gmail失败:无法加载数据或仅显示纯文本
问题原因
- 原有代码配置
mailtype为text,且直接将ics原始内容作为邮件正文发送,Gmail无法识别对应的MIME类型,因此仅展示为纯文本 - 调用
attach()方法报错是因为CodeIgniter Email类的attach()方法默认首个参数为本地文件路径,直接传入ics字符串会尝试读取不存在的本地文件,触发“unable to load request data”错误 - 额外注意:原有ics内容的
DTSTAMP、DTSTART、DTEND字段未遵循iCal标准的UTC时间格式(YYYYMMDDTHHMMSSZ),直接传入时间戳也会导致日历事件无法被正常识别
修复方案
步骤1:修正iCal内容格式
将所有时间字段转换为iCal标准格式,示例代码:
// 假设$event['start_event']和$event['end_event']为Unix时间戳 $start = gmdate('Ymd\THis\Z', $event['start_event']); $end = gmdate('Ymd\THis\Z', $event['end_event']); $dtstamp = gmdate('Ymd\THis\Z', time()); $ical = 'BEGIN:VCALENDAR VERSION:2.0 PRODID:-//hacksw/handcal//NONSGML v1.0//EN CALSCALE:GREGORIAN METHOD:REQUEST BEGIN:VEVENT DTEND:' . $end . ' UID:' . md5($event['title']) . '@yourdomain.com DTSTAMP:' . $dtstamp . ' SUMMARY:' . addslashes($event['title']) . ' DTSTART:' . $start . ' END:VEVENT END:VCALENDAR';
注意:UID字段建议加后缀域名,避免和其他日历事件冲突,同时顶层VCALENDAR节点增加METHOD:REQUEST声明
步骤2:修正邮件配置与发送逻辑
将mailtype改为html,直接以字符串附件形式传入ics内容,无需手动设置header:
$config['protocol'] = 'ssmtp'; $config['smtp_host'] = 'ssl://ssmtp.gmail.com'; $config['smtp_port'] = '465'; $config['smtp_timeout'] = '7'; $config['smtp_user'] = 'mail@gmail.com'; // 注意:现在Gmail普通账号密码无法直接登录,需要开启两步验证后生成应用密码填入此处 $config['smtp_pass'] = '你的Gmail应用密码'; $config['charset'] = 'utf-8'; $config['newline'] = "\r\n"; // 把mailtype改成html,支持多部分内容 $config['mailtype'] = 'html'; $config['validation'] = TRUE; $this->email->initialize($config); $this->email->from('from@myc2s.com', $from); $this->email->to('to@gmail.com'); $this->email->subject('ICS日历邀请'); // 邮件正文可以写普通文本/HTML内容,不影响ics附件识别 $this->email->message('这是一封日历邀请邮件,你可以点击附件添加到日历。'); // 核心:直接传递ics字符串作为附件,不需要存本地文件 // CodeIgniter 3+ 支持attach方法第五个参数传入附件内容字符串 $this->email->attach( '', // 第一个参数留空,因为我们传内容字符串 'attachment', 'meeting.ics', 'text/calendar; method=REQUEST; charset=utf-8', $ical // 第五个参数传ics字符串内容 ); $sendmessage = $this->email->send();
如果你的CodeIgniter版本较低不支持第五个参数,可以生成临时文件再挂载:
// 生成临时文件 $temp_file = tempnam(sys_get_temp_dir(), 'ics'); file_put_contents($temp_file, $ical); $this->email->attach($temp_file, 'attachment', 'meeting.ics', 'text/calendar; method=REQUEST'); $sendmessage = $this->email->send(); // 发送完成后删除临时文件 unlink($temp_file);
内容的提问来源于stack exchange,提问作者Thariq
相关产品推荐
相关产品推荐

