如何使用PHP动态发布可被Google日历读取的ical文件?


106

Google对PHP ical的任何搜索都只会显示phpicalendar以及如何解析或读取IN ical文件。我只想编写一个PHP文件,该文件从数据库中提取事件并以ical格式将其写出。

我的问题是我找不到任何地方可以回答两个问题:

  1. 确切的文件格式是什么,包括页眉,文件格式,页脚等?换句话说,要由Google日历等正确读取文件,文件必须具有什么内容?
  2. 如果我使用.php扩展名构建此文件,该如何将其发布为ical?是否需要写入新的.ics文件?还是只要内容的格式正确,Google日历等都会读取.php文件为ical吗?(如果内容实际上是CSS等,则类似于style.css.php文件将被读取为CSS文件。)

大家可以提供或指向我的任何帮助将不胜感激!!!

Answers:


128

如果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文件的全部所需内容,即使在缓存,文本编码等方面可能存在一些问题。但是您可以开始尝试使用此简单代码。


1
谢谢。我认为这些标题是我所缺少的。我认为要准备好此Google日历还有最后几个步骤,因为当我尝试通过URL将文件提交到Google日历时,它说“正在从url导入日历...”,但是会永久挂起。也许这是一个不同的问题要发布吗?
rhodesjason

3
究竟。我更新了上面的示例-并且还添加了DTSTAMP属性,该属性将告诉客户端事件已更新的时间。
Stefan Gehrig

1
好吧,格里格,你真是个天才。那行得通。谢谢。(据我所知,Google日历几乎也立即更新。)
rhodesjason

3
如果我没错的话。程序使用UID查看事件是否被删除。如果一个php脚本始终生成另一个UID(-> mt_rand),程序将始终认为整个内容已更改。一切都消失了,一切都是新的。就个人而言,如果事件在数据库中相同,我会坚持使用相同的UID,而仅使用recordID(和一些主机信息)。DTSTAMP在那里表明发生了某些变化。那应该足够了。
Seirddriezel

3
Google日历确实需要* .ics-extension。如果您使用的是.htaccess,则可以通过添加 RewriteEngine on RewriteRule ^calendar.ics$ my_php_script.php [QSA]
Fanky

19

除了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文件正确验证。


标头信息对于未来的任何人来说都是重要的信息。大多数情况下,大多数应用程序和程序不必担心换行符中断。似乎只有验证者这样做。但是最重​​要的是标题部分。我们尝试了一段时间,但没有遇到任何问题。
jfreak53 2015年

1
escapeString的作用是什么?我以为它应该逃避一两个东西,但是您似乎可以htmlspecialchars代替它。
卢克,2016年

1
快速修复:date('Ymd \ THis \ Z',$ timestamp)。应该是H而不是g。
PedroGóes17年

6

有一个出色的eluceo / ical软件包,可让您轻松创建ics文件。

这是docs中的示例用法:

// 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

http://www.kanzaki.com/docs/ical/具有较旧规范的可读性更高的版本。作为起点,它很有帮助-许多事情还是一样。

同样在我的网站

  1. 某些有用资源的列表(请参见右下方的侧栏)
    • 规范RFC 5545
    • 物理测试资源
  2. .ics在过去的几年中,我的工作经历记录了一些笔记。特别是,您可能会发现此重复事件“备忘单”很有用。

.ics 需要仔细处理的区域:

  • “全天”活动
  • 日期类型(时区,UTC或本地“浮动”)-要了解区别,请使用nb
  • 重复规则的互操作性

2
  1. 确切格式:http//www.ietf.org/rfc/rfc2445.txt
  2. 根据规范,它必须以.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类型在服务器上配置。


1
我已经尝试阅读过很多次该规范,但我无法根据ical文件的外观做出正面或反面的描述。您能否至少将我指向一些行,以开始讨论.ics文件中标头应包含的内容,放置MIME类型的位置等?
2009年

2

确保您格式化这样的字符串,否则它将无法正常工作

 $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";

1
最好使用PHP_EOL代替"\n"
是Barry

4
PHP_EOL是特定于终端线的环境,因此在Windows中它将输出,\r\n因此请记住这一点!
克里斯(Chris
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.