7

我用 PHP 5 和 MySQL 构建了一个站点,其中包含一个跟踪预定照片拍摄的表。我想将这些预定“事件”的提要推送到 ical 文件中。

我最初问了这个问题,并从S. Gehrig那里得到了很好的回答。每当我在 Dreamweaver 中手动调整文件时,我得到了一个可用的示例 ical 文件,并在 Google 日历中定期更新。但是,既然我已经添加了从数据库中提取的动态 PHP,它就不起作用了。

这是PHP:

<?php
require_once('../../_includes/initialize.php');

$ical = " BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN ";

$slots = Slot::find_all();
foreach($slots as $slot) {
    $job = Job::find_by_id($slot->job_id);

    $start_stamp = strtotime($slot->start);
    $end_stamp = strtotime($slot->endtime);
    $dtstart = gmdate('Ymd', $start_stamp).'T'. gmdate('His', $start_stamp) . "Z"; // converts to UTC time
    $dtend = gmdate('Ymd', $end_stamp).'T'. gmdate('His', $end_stamp) . "Z"; // converts to UTC time

    $summary = $job->title;

    $ical .= " BEGIN:VEVENT
    UID:" . $slot->id . "@homewoodphoto.jhu.edu
    DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z
    DTSTART:" . $dtstart . "
    DTEND:" . $dtend . "
    SUMMARY:" . $summary . "
    END:VEVENT ";
}

$ical .= " END:VCALENDAR";

//set correct content-type-header
header('Content-type: text/calendar; charset=utf-8');
header('Content-Disposition: inline; filename=homewoodphoto_master.ics');
echo $ical;
exit;

?>

据我所知,该文件的输出与我正在使用的手动硬编码版本完全相同。谁能看到为什么这不起作用????

PS 这是正在运行的文件的代码——我刚刚将它发布在我的服务器上并通过谷歌日历中的 URL 订阅。当我在第二个事件中进行硬编码时,它很快就单独出现在 Google 日历中。

<?php

$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:20090925T170000Z
DTEND:20090928T035959Z
SUMMARY:Bastille Day Party
END:VEVENT

BEGIN:VEVENT
UID:" . md5(uniqid(mt_rand(), true)); . "@yourhost.test
DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z
DTSTART:20090929T170000Z
DTEND:20090930T035959Z
SUMMARY:Camping Trip
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;

?>

帮助!

一位评论者建议我通过删除标题并回显 $ical var 来进行测试。以下是该测试的结果,为方便起见添加了换行符:

BEGIN:VCALENDAR 
VERSION:2.0 
PRODID:-//hacksw/handcal//NONSGML v1.0//EN 
BEGIN:VEVENT 
UID:21@homewoodphoto.jhu.edu 
DTSTAMP:20090929T212141Z 
DTSTART:20091001T230000Z 
DTEND:20091001T230000Z 
SUMMARY:little title 
END:VEVENT 
BEGIN:VEVENT 
UID:22@homewoodphoto.jhu.edu 
DTSTAMP:20090929T212141Z 
DTSTART:20090926T230000Z 
DTEND:20090927T010000Z 
SUMMARY:A big photo shoot 
END:VEVENT 
BEGIN:VEVENT 
UID:23@homewoodphoto.jhu.edu 
DTSTAMP:20090929T212141Z 
DTSTART:20091003T230000Z 
DTEND:20091004T010000Z 
SUMMARY:A big photo shoot 
END:VEVENT 
END:VCALENDAR

谢谢!

4

3 回答 3

20

对于通过搜索偶然发现的人来说,可能不清楚问题是如何解决的。基本上,iCal 规范要求 \r\n 用于换行符,并且行首没有空格,这是脚本中修复的使其工作的内容。

在使用 ical 时,我发现以下 3 个验证器最有帮助:

最基本的(错过空格):http ://severinghaus.org/projects/icv/?url=

这个会抓住空格:http: //icalvalid.cloudapp.net/Default.aspx

这个会捕捉到其他人没有但几乎过于严格的东西:http: //arnout.engelen.eu/icalendar-validator

此外,关于所有不同元素的最佳文档:http ://www.kanzaki.com/docs/ical/

于 2010-11-04T19:42:52.500 回答
2

最初的猜测是您的数组未正确填充。所以要测试它,我将从删除

//set correct content-type-header
header('Content-type: text/calendar; charset=utf-8');
header('Content-Disposition: inline; filename=homewoodphoto_master.ics');

并改变 $slots = Slot::find_all(); 至

$slots = Slot::find_all();
print_r($slots); 

确保正在设置您的对象数组。

然后从命令行或浏览器运行它,以确保它在提交给 google 之前按预期输出。

尝试以下代码以避免空格:

<?php
require_once('../../_includes/initialize.php');

$ical = "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//hacksw/handcal//NONSGML v1.0//EN";

$slots = Slot::find_all();
foreach($slots as $slot) {
    $job = Job::find_by_id($slot->job_id);

    $start_stamp = strtotime($slot->start);
    $end_stamp = strtotime($slot->endtime);
    $dtstart = gmdate('Ymd', $start_stamp).'T'. gmdate('His', $start_stamp) . "Z"; // converts to UTC time
    $dtend = gmdate('Ymd', $end_stamp).'T'. gmdate('His', $end_stamp) . "Z"; // converts to UTC time

    $summary = $job->title;

    $ical .= "BEGIN:VEVENT\n";
    $ical .= "UID:" . $slot->id . "@homewoodphoto.jhu.edu\n";
    $ical .= "DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z\n";
    $ical .= "DTSTART:" . $dtstart . "\n";
    $ical .= "DTEND:" . $dtend . "\n";
    $ical .= "SUMMARY:" . $summary . "\n";
    $ical .= "END:VEVENT\n";
}

$ical .= "\nEND:VCALENDAR";

//set correct content-type-header
header('Content-type: text/calendar; charset=utf-8');
header('Content-Disposition: inline; filename=homewoodphoto_master.ics');
echo $ical;
exit;

?>
于 2009-09-29T21:16:04.250 回答
1

感谢 Mohammad 的帮助,我们推断是缩进代码向 ics 文件添加了空格导致了错误。M 建议使用 \n 换行符不起作用,但手动按回车键创建换行符,但不缩进下一行,似乎已经做到了。这是有效的代码:

<?php
require_once('../../_includes/initialize.php');

$ical = "BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
";

$slots = Slot::find_all();
foreach($slots as $slot) {
$job = Job::find_by_id($slot->job_id);

$start_stamp = strtotime($slot->start);
$end_stamp = strtotime($slot->endtime);
$dtstart = gmdate('Ymd', $start_stamp).'T'. gmdate('His', $start_stamp) . "Z"; // converts to UTC time
$dtend = gmdate('Ymd', $end_stamp).'T'. gmdate('His', $end_stamp) . "Z"; // converts to UTC time

$summary = $job->title;

$ical .= "BEGIN:VEVENT
UID:" . $slot->id . "@homewoodphoto.jhu.edu
DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z
DTSTART:" . $dtstart . "
DTEND:" . $dtend . "
SUMMARY:" . $summary . "
END:VEVENT
";
}

$ical .= "END:VCALENDAR";

//set correct content-type-header
header('Content-type: text/calendar; charset=utf-8');
header('Content-Disposition: inline; filename=homewoodphoto_master.ics');
echo $ical;
exit;
?>
于 2009-09-30T12:40:43.810 回答