Erstellen und Exportieren von iCal-Dateien (.ics) mit Hilfe von PHP
Kalender-Dateien wie iCal folgen einer festgelegte Struktur, damit verschiedene Programme mit den Dateien arbeiten können. Mit PHP könnt ihr Dateien im .ics-Format erstellen und auf eurer Website zum Download anbieten.

Termin- oder Veranstaltungskalender sind schon lange keine Seltenheit mehr im Internet. Mit Hilfe von PHP können diese Termindaten auch als iCal-Datei (*.ics) auf Websites zum Download angeboten werden, ohne dass man von Hand eine solche Datei erstellen muss. Die Benutzer der Website können sich somit komfortabel diese Termine in ihren eigenen elektronischen Kalender importieren. In diesem Beitrag findet ihr das passende PHP-Snippet, um auch euren Benutzern ein iCal-Export zur Verfügung zu stellen.
Daten auslesen und in Variablen speichern
Um eure iCal-Datei mit den richtigen Daten zu füllen, erstellt ihr als erstes einige Variablen mit euren Daten. Diese werden später an das Skript übergeben. In diesem Beispiel handelt es sich um folgende Angaben:
- Start des Termins (Datum und Zeitpunkt)
- Ende des Termins (Datum und Zeitpunkt)
- Erstellung des Termins (Datum und Zeitpunkt)
- Titel der Veranstaltung
- Veranstaltungsort
- Beschreibung der Veranstaltung
- Link zur Veranstaltung
- Dateiname der iCal-Datei
Hierbei ist es wichtig, dass die Datums- und Zeitangaben im Format »YYYYMMDDTHHMMSS
« vorliegt. Angaben wie der Titel, die Beschreibung und der Veranstaltungsort werden mit Hilfe von PHP so formatiert, dass sie später auch korrekt angezeigt werden. Der Dateiname sollte webfreundlich, d. h. ohne Sonderzeichen oder Leerzeichen angegeben werden.
$kb_start = '20161028T130000';
$kb_end = '20161028T143000';
$kb_current_time = '20161026T130000';
$kb_title = html_entity_decode('Titel des Termins', ENT_COMPAT, 'UTF-8');
$kb_location = preg_replace('/([\,;])/','\\\$1','Location');
$kb_description = html_entity_decode('Beschreibung zum Termin', ENT_COMPAT, 'UTF-8');
$kb_url = 'https://kulturbanause.de';
$kb_file_name = 'name-der-datei';
iCal-Datei erstellen
Das Erstellen der iCal-Datei funktioniert in drei Schritten. Als erstes wird die Datei mitels fopen()
geöffnet, anschließend mittels fwrite()
der Inhalt eingefügt und zuletzt die Datei mittels fclose() geschlossen. Das alles passiert, sobald jemand die Seite aufruft, auf der das folgende Code-Snippet eingebunden ist. Sobald ein zweiter Seitenaufruf stattfindet, wird diese Datei aktualisiert. Der Pfad eures Verzeichnisses muss im Code an die Stelle des Wortes »VERZEICHNIS
« geschrieben werden. Sollte aus irgendeinem Grund (z. B. falsche Schreibrechte eures Verzeichnisses) die Datei nicht geöffnet werden können, bricht das Script ab und es erscheint der Satz »Datei kann nicht gespeichert werden!«.
<?php $kb_ical = fopen('VERZEICHNIS/'.$kb_file_name.'.ics', 'w') or die('Datei kann nicht gespeichert werden!');
$eol = "\r\n";
$kb_ics_content =
'BEGIN:VCALENDAR'.$eol.
'VERSION:2.0'.$eol.
'PRODID:-//kulturbanause//kulturbanause.de//DE'.$eol.
'CALSCALE:GREGORIAN'.$eol.
'BEGIN:VEVENT'.$eol.
'DTSTART:'.$kb_start.$eol.
'DTEND:'.$kb_end.$eol.
'LOCATION:'.$kb_location.$eol.
'DTSTAMP:'.$kb_current_time.$eol.
'SUMMARY:'.$kb_title.$eol.
'URL;VALUE=URI:'.$kb_url.$eol.
'DESCRIPTION:'.$kb_description.$eol.
'UID:'.$kb_current_time.'-'.$kb_start.'-'.$kb_end.$eol.
'END:VEVENT'.$eol.
'END:VCALENDAR';
fwrite($kb_ical, $kb_ics_content);
fclose($kb_ical);
?>
Datei zum Download bereitstellen
Um die Datei nun zum Download anzubieten, könnt ihr einen ganz gewöhnlichen Link erstellen. Gebt hier ebenfalls den von euch gewählten Verzeichnispfad und den von euch gewählten Dateinamen an.
<a href="./VERZEICHNIS/<?php echo $kb_file_name; ?>.ics" title="»<?php echo $kb_title; ?>« exportieren">Termin in Kalender speichern</a>
Anpassung der .htaccess
-Datei
Sollte euer Browser die Datei anzeigen anstatt den Download zu starten, müsst ihr gegebenenfalls eure .htaccess
-Datei anpassen. Um sicher zu stellen, dass die von euch erstellte Datei als Download-Datei erkannt wird und nicht direkt im Browser geöffnet wird, schreibt folgende Zeile in eure .htaccess
-Datei. Erstellt allerdings vorher unbedingt ein Backup der alten .htaccess
, da Fehler in dieser Datei die Website beschädigen können.
AddType text/calendar .ics
Live-Beispiel
Das folgende Live-Beispiel zeigt die o.g. Funktionalität. Per Klick ladet ihr eine *.ics
-Datei herunter, die ein Event des heutigen Tages beinhaltet.
Es gibt ein Problem bei den ics export Dateien, das ich nicht lösen kann:
Wenn ich ics Dateien erzeuge (auch mit Ihrem Script) und in ein Verzeichnis meines Servers stelle, importiert nur ein Teil der Ferienvermietungs- und Buchungsportale die Kalenderdaten aus der ics Datei. Das passiert auch, wenn ich Versuchsweise Ihre ics Beispieldatei auf meinen Server stelle. Interessanterweise funktioniert aber folgendes: Gebe ich Ihren Link „https://media.kulturbanause.de/2016/10/beispiel-ical-export.ics“ direkt ein, wird die Datei sofort importiert. Meiner Meinung nach liegt das Problem also nicht an der Icaldatei, sondern an meinem Server. Frage: Welche Anforderungen muss also mein Server bzw. mein Verzeichnis aufweisen, damit meine ics feed Dateien angenommen werden? Für entsprechende Hilfe wäre ich sehr dankbar.
Viele Grüße Reinhold Schweitzer
Inzwischen habe ich herausgefunden, dass der Exportkalender von jedem anderen ausprobierten Hosting ohne jede Einschränkung von den Bookingportalen angenommen wird und funktioniert, vorausgesetzt er besitzt Leserechte. Also liegt das Problem tatsächlich an meinem Webspace. Mein Provider hat auf meine Anfrage lediglich auf folgendes hingewiesen, dass „Zwischen dem 18.11. und 21.11. traten Netzwerkstörungen auf, die u.a. Verbindungen verlangsamt oder zu Paketverkust geführt haben können.“ Das das Problem aber bereits seit langem besteht und unabhängig von kurzfristigen Störungen auftritt, wird anscheinend einfach ignoriert.
Hallo Robert
Toller Skript, funktioniert perfekt!
Ein Frage hätte ich noch betreffend Serientermin.
Folgende Optionen interessieren mich:
1. Serientermin mit Enddatum
2. Serientermin mit Anzahl (z.B. 25 Wiederholungen, immer am betreffenden Tag)
Freundlich grüsst
Beat
Herzlichen Dank Roman
Im Link https://www.rfc-editor.org/info/rfc5545 fand ich die gesuchte Lösung!
Das hat mir sehr geholfen!
Sie im Dokument unter FREQ:
RRULE:FREQ=WEEKLY;UNTIL=19971224T000000Z
=> (1997 9:00 AM EDT) September 2,9,16,23,30; October 7,14,21
(1997 9:00 AM EST) October 28;
November 4,11,18,25;
December 2,9,16,23
Hallo Robert,
das ist ein tolles und einfach zu verwendendes Script. Hat sofort geklappt.
Über den Desktop-Browser wird die ics-Datei auch sauber herunter geladen und kann dann geöffnet werden.
Wenn ich die Datei über mein iPhone aufrufe, kommt aber immer die Fehlermeldung „Safari kann die Datei nicht laden“.
Mit Deinem Beispiel funktioniert es aber einwandfrei. Hast Du einen Tipp woran das liegen könnte?
Danke und Gruß
Robert
Hallo Robert,
so aus der Ferne kann ich das nicht beurteilen.
Öffne deine ics Datei und die Datei aus dem Beispiel doch einmal in einem Code-Editor und schaue ob du irgendwo Abweichungen feststellen kannst.
Viele Grüße
Robert
Super Beitrag, eigentlich genau das was ich gesucht habe :)
Nur ist es bei mir ein Wenig komplizierter und wollte daher mal fragen ob jemand dafür eine Lösung hat.
Ich habe für unsere Pfadi eine neue Website (WordPress) erstellt und nun haben wir eine Agenda (von Google Kalender eingespeist), auf welcher man die Kalendereinträge gleich zu seinem eigenen Google Kalender Konto hinzufügen kann.
Hier unsere Seite: https://pfadigottstatt.ch/agenda/
Nun fände ich es aber nice, wenn man auf dem Smartphone den Kalendereintrag per .ics Datei auch in den iCalendar speichern könnte. Zum Beispiel so wie hier: https://www.pfadialphacentauri.ch/programmpunkte?category=Biber
Allerdings benutzt diese Pfadi das Tool von Squarespace und daher weiss ich nicht, ob sie die Einträge auch vom Google Kalender einspeisen oder selber in Squarespace eintragen. Gäbe es vielleicht eine Möglichkeit, diese Funktion auf unserer Seite einzubinden?
Vielen Dank und beste Grüsse
Joël
Hallo Joël,
hier können wir dir leider ohne größere Recherche nicht weiterhelfen.
Wir hoffen du konntest bereits eine Lösung finden oder findest eine.
Viele Grüße
Robert
Hallo,
danke für die Anleitung, funktioniert so weit, ich mache kein Download, ich versende die Datei per E-Mail, soll als Urlaubserinnerung für die Vertretung sein… KLappt alles, außer, wenn ich den Termin öffne, steht immer das Start und Enddatum gleich drin, obwohl der Urlaub von 29.10.2019 – 31.10.2019 ist, steht in der Vorauswahl bei Start und Ende der 29.10.2019.
Muss ich etwas ändern, wenn ich Zeitraum über mehrere Tage habe?
Danke und Grüße
Erik
Hallo Erik, du kannst dir hier anschauen, wie wir ein dreitägiges Event ausgezeichnet haben. Vielleicht hilft dir das weiter.
Hallo,
vielen Dank für die Anleitung.
Ich könnte sowas über JS gebrauche, denn ich möchte diese Datei OnTheFly erzeugen, wenn ich auf einen Link „Im Kalender speichern“ klicke.
Hat jemand für mich einen Tip mit dem es auch funktioniert?
Mit https://github.com/nwcell/ics.js komme ich nicht weiter, weil iOS 12/13 die Datei im Browser nicht erkennt oder nicht valide hält und somit ich den Screen zum eintragen in den Kalender nicht direkt erhalte.
Danke für Eure Hilfe.
Hallo, leider verstehe ich nicht, wie ich die Dateien einfügen muss. Soll ich das ganze snippet in der home.php einfügen oder alles in einer extra Datei? Kann mir jemand bitte nochmal die genauen Schritte, wie und was ich wo einfügen muss erklären? Vielen Dank.
Ich habe folgendes herausgefunden:
Wenn ich den Link: http://media.kulturbanause.de/2016/10/beispiel-ical-export.ics angebe wird dieser sofort akzeptiert und importiert. Ich gehe lt. Quelltext davon aus, dass die Datei lediglich als Datei im Verzeichnis steht und nicht dynamisch erzeugt wird. Also muss ich jetzt noch herausfinden, warum meine Datei nicht funktioniert.
Danke für dieses tolle Script. Mit einigen Abänderungen konnte ich sogar einen Belegungskalender zum Download anbieten der gar nicht als icalendar konzipiert ist!
Meine Frage:
Wie kann ich einen Importlink anbieten, der automatisch den erzeugten Kalender z.B. mit einem Cronjob täglich abruft? Den erzeugten Kalender als ics-Datei in ein Verzeichnis zu stellen und abrufen zu lassen funktioniert nicht. Danke!
Hallo Reinhold, du müsstest die ical-Datei eigtl. nur öffentlich unter einer URL verfügbar machen und dort bei Änderungen aktualisieren. In den Kalendern kann man dann diese URL abonnieren und als Nutzer festlegen wie oft Updates geladen werden sollen.
Danke für die Antwort. Aber noch wie bereits geschrieben: „Den erzeugten Kalender als ics-Datei in ein Verzeichnis zu stellen und abrufen zu lassen funktioniert nicht!“ Die Fehlermeldungen lauten dann etwa „Kein gültiger ics-Importlink“.
Im ical-validator wird die gleiche Datei anstandslos akzeptiert, auch in den Google Kalender kann ich sie ohne Probleme einfügen.
Hallo,
besten Dank!
Gut und leicht verständlich beschrieben.
Ich verschicke die Termine per Messenger.
So hat die dann jeder im Verein auch gleich auf seinem Smartphone pder Endgerät seiner Wahl.
Super script, vielen Dank!
Kann das auch für mehrere Termine in 1 File verwendet werden oder muss die ics syntax dafür angepasst werden?
LG Wolfgang
Hallo,
prima Anleitung – danke dafür.
Besteht auch die Möglichkeit, statt eines festen Datums eine dynamische Datum (bspw. immer von jetzt an in 24 Stunden) einzuspielen?
VG
McCormick
Hallo,
wenn du im oben beschriebenen Code die Variable $kb_start bzw. $kb_end mit dem aktuellen Zeitstempel (+ 24h) befüllst, ist das Datum je nach Download der Datei verschieden.
MfG Robert
Hi und einfach erklärt,
kann man diese iCal dann auch abonnieren wenn man dies in seinem Script berücksichtigt? So das man dann auf allen Geräten die selbe Information hat?
Oder geht damit nur ein einfacher Import?
Hallo Andreas,
mit dem hier beschriebenen Code wird nur eine einzelne Datei heruntergeladen, die anschließend in den Kalender importiert werden muss. Wenn du deine Geräte miteinander synchronisiert hast, erscheint dieser Termin dann natürlich in all deinen Kalendern.
Das ergibt aber kein valides iCal und wird so auch von Google-Calendar abgelehnt:
https://icalendar.org/validator.html?url=http://media.kulturbanause.de/2016/10/beispiel-ical-export.ics
Danke für den Hinweis. Wir haben die Fehler behoben und Google importiert nun auch fehlerfrei. Der Validator meckert noch bei den Zeilenumbrüchen. Hier weiß ich gerade nicht wie ich den Fehler beheben kann – vielleicht hast du einen Tipp. Aber in der Praxis läuft alles.
kein Meckern bei den Zeilenumbrüchen mit:
$clf = „\r\n“;
$kb_ics_content = ‚BEGIN:VCALENDAR‘.$clf;
$kb_ics_content .= ‚VERSION:2.0‘.$clf;
etc..
Das Validierungsproblem ist behoben. Besten Dank!
Hallo,
Toller Beitrag – läuft super !
Es gab den Hinweis :
Fehler behoben und Google importiert nun auch fehlerfrei.
wie sieht das Script nun aus ?
Es werden zb. in title und Location keine Umlaute angezeigt.
Wie kann man das beheben.
Vielen Dank
Günther Kendl
Hallo Günther, wir haben die Fehler direkt oben im Skript behoben. Mit falschen Sonderzeichen haben wir bisher keine Probleme.
Super Beitrag. Werde ich direkt mal ausprobieren. Woher kommt die Syntax für den $kb_ics_content und gibt es da noch andere Optionen?
VG
mb7
Besser spät als nie ;)
Das Datenformat zum Austausch von Kalenderinhalten ist in RFC 5545 standardisiert –> https://www.rfc-editor.org/info/rfc5545
Dort sollte man sich auch die Updates anschauen. Speziell das Update RFC 5546 , weil dort unter Punkt 4 jede Menge Beispiele aufgeführt werden.
Der Wikipedia-Eintrag ist auch ganz interessant –> https://de.wikipedia.org/wiki/ICalendar
Ich hoffe, dass es jemandem weiterhilft :)
Ich nutze immer das ICS package von jsvrcek
https://packagist.org/packages/jsvrcek/ics
Grüße
Danke für den Tipp. Die Library ist echt cool :)