如何使用 PHP 动态发布 ical 文件以供 Google 日历读取?
Posted
技术标签:
【中文标题】如何使用 PHP 动态发布 ical 文件以供 Google 日历读取?【英文标题】:How can I use PHP to dynamically publish an ical file to be read by Google Calendar? 【发布时间】:2010-11-30 14:42:36 【问题描述】:在 php ical 上的任何 Google 搜索都会显示 phpicalendar 以及如何解析或读取 IN ical 文件。我只想编写一个 PHP 文件,从我的数据库中提取事件并以 ical 格式写出。
我的问题是我找不到可以回答两个问题的地方:
-
确切格式是什么,包括页眉、文件格式、页脚等?换句话说,该文件究竟必须具备什么才能被 Google 日历等正确读取?
如果我使用 .php 扩展名构建此文件,如何将其发布为 ical?我必须写入新的 .ics 文件吗?或者只要内容格式正确,Google Calendar 等是否会读取 .php 文件? (很像 style.css.php 文件如果内容实际上是 CSS 等,则会被读取为 CSS 文件等)
大家可以给予或指点我的任何帮助将不胜感激!!!
【问题讨论】:
【参考方案1】:如果 Google 日历不需要 *.ics
-extension(这将需要在服务器中重写一些 URL),这应该非常简单。
$ical = "BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
BEGIN:VEVENT
UID:" . md5(uniqid(mt_rand(), true)) . "@yourhost.test
DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z
DTSTART:19970714T170000Z
DTEND:19970715T035959Z
SUMMARY:Bastille Day Party
END:VEVENT
END:VCALENDAR";
//set correct content-type-header
header('Content-type: text/calendar; charset=utf-8');
header('Content-Disposition: inline; filename=calendar.ics');
echo $ical;
exit;
这基本上就是让客户认为您正在提供 iCalendar 文件所需的全部内容,即使在缓存、文本编码等方面可能存在一些问题。但是您可以开始尝试这个简单的代码。
【讨论】:
谢谢。我认为这些标题是我所缺少的。我假设准备好这个谷歌日历有几个最后的步骤,因为当我尝试通过 URL 将此文件提供给谷歌日历时,它说“从 url 导入日历......”但永远挂在上面。也许这是一个不同的问题要发布? 没错。我更新了上面的示例 - 我还添加了一个 DTSTAMP 属性,它将在事件更新时告诉客户端。 好吧,Gehrig,你是个天才。那行得通。谢谢。 (据我所知,Google 日历也几乎立即更新。) 如果我没记错的话。程序使用 UID 来查看是否删除了事件。如果一个 php-script 总是生成另一个 UID (->mt_rand),程序总是会认为整个内容已经改变。一切都消失了,一切都是新的。如果数据库中的事件相同,我个人会坚持使用相同的 UID,并且只使用记录 ID(和一些主机信息)。 DTSTAMP 用于显示发生了变化。应该够了。 Google 日历确实需要 *.ics 扩展名。如果你使用.htaccess,你可以通过添加RewriteEngine on
RewriteRule ^calendar.ics$ my_php_script.php [QSA]
【参考方案2】:
除了 Stefan Gehrig 的回答和 Dave None 的回答(以及 mmmshuddup 的回答)之外的个人经历:
当我在http://severinghaus.org/projects/icv/ 使用 ICS 验证器时,我在使用 \n 和 PHP_EOL 时遇到了验证问题
我了解到我必须使用 \r\n 才能使其正确验证,所以这是我的解决方案:
function dateToCal($timestamp)
return date('Ymd\Tgis\Z', $timestamp);
function escapeString($string)
return preg_replace('/([\,;])/','\\\$1', $string);
$eol = "\r\n";
$load = "BEGIN:VCALENDAR" . $eol .
"VERSION:2.0" . $eol .
"PRODID:-//project/author//NONSGML v1.0//EN" . $eol .
"CALSCALE:GREGORIAN" . $eol .
"BEGIN:VEVENT" . $eol .
"DTEND:" . dateToCal($end) . $eol .
"UID:" . $id . $eol .
"DTSTAMP:" . dateToCal(time()) . $eol .
"DESCRIPTION:" . htmlspecialchars($title) . $eol .
"URL;VALUE=URI:" . htmlspecialchars($url) . $eol .
"SUMMARY:" . htmlspecialchars($description) . $eol .
"DTSTART:" . dateToCal($start) . $eol .
"END:VEVENT" . $eol .
"END:VCALENDAR";
$filename="Event-".$id;
// Set the headers
header('Content-type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename=' . $filename);
// Dump load
echo $load;
这阻止了我的解析错误并使我的 ICS 文件正确验证。
【讨论】:
标头信息是供任何展望未来的人参考的重要部分。在大多数情况下,大多数应用程序和程序都不担心换行符。似乎只有验证者才会这样做。但最重要的是标题部分。我们在没有它的情况下尝试了一段时间,但遇到了很多问题。 escapeString 是干什么用的?我认为它应该逃避一两件事,但您似乎使用htmlspecialchars
代替。
快速修复:date('Ymd\THis\Z', $timestamp)。应该是 H 而不是 g。【参考方案3】:
有一个出色的eluceo/ical 包,可以让您轻松创建 ics 文件。
这是来自文档的示例用法:
// 1. Create new calendar
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
// 2. Create an event
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2012-12-24'));
$vEvent->setDtEnd(new \DateTime('2012-12-24'));
$vEvent->setNoTime(true);
$vEvent->setSummary('Christmas');
// Adding Timezone (optional)
$vEvent->setUseTimezone(true);
// 3. Add event to calendar
$vCalendar->addComponent($vEvent);
// 4. Set headers
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="cal.ics"');
// 5. Output
echo $vCalendar->render();
【讨论】:
【参考方案4】:可能有点晚了,但这里有一个指向实际规范的链接。 https://www.rfc-editor.org/rfc/rfc5545[1]
【讨论】:
【参考方案5】:http://www.kanzaki.com/docs/ical/ 具有较旧规范的可读性稍高的版本。作为一个起点,它会有所帮助 - 许多事情还是一样的。
还有my site,我有
-
一些有用资源的列表(见右下角边栏)
特殊规范 RFC 5545
ical 测试资源
Some notes 记录了我过去几年与
.ics
合作的旅程。特别是,您可能会发现此repeating events 'cheatsheet' 很有用。
.ics
需要小心处理的地方:
【讨论】:
【参考方案6】:-
确切格式:http://www.ietf.org/rfc/rfc2445.txt
根据规范,它必须以 .ics 结尾
编辑:实际上我不确定 - 第 6186 行给出了 .ics 命名格式的示例,但它也声明您可以使用 url 参数。我认为这并不重要,只要 MIME 类型正确即可。
编辑:来自***的示例:http://en.wikipedia.org/wiki/ICalendar
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
BEGIN:VEVENT
DTSTART:19970714T170000Z
DTEND:19970715T035959Z
SUMMARY:Bastille Day Party
END:VEVENT
END:VCALENDAR
在服务器上配置了 MIME 类型。
【讨论】:
我已尝试多次阅读该规范,但就 ical 文件的外观而言,我无法确定它的正面或反面。您能否至少指出一些行,它开始实际讨论 .ics 文件应包含的内容,包括标题、MIME 类型的放置位置等?【参考方案7】:确保你像这样格式化字符串,否则它将不起作用
$content = "BEGIN:VCALENDAR\n".
"VERSION:2.0\n".
"PRODID:-//hacksw/handcal//NONSGML v1.0//EN\n".
"BEGIN:VEVENT\n".
"UID:".uniqid()."\n".
"DTSTAMP:".$time."\n".
"DTSTART:".$time."\n".
"DTEND:".$time."\n".
"SUMMARY:".$summary."\n".
"END:VEVENT\n".
"END:VCALENDAR";
【讨论】:
最好使用PHP_EOL
而不是"\n"
。
PHP_EOL 是特定于结束行的环境,因此在 Windows 中它将输出 \r\n
所以请记住这一点!以上是关于如何使用 PHP 动态发布 ical 文件以供 Google 日历读取?的主要内容,如果未能解决你的问题,请参考以下文章
Google Calendar PHP API v3 中的 ical() 类需要哪个 PHP 脚本文件
如何在Javascript中创建动态文件+链接以供下载? [复制]