PHPGangsta - Der praktische PHP Blog

PHP Blog von PHPGangsta


Adress- und Kontaktdaten als VCard exportieren

with 13 comments

VCards sind kleine Dateien, die Personen- und Adressbuch-Daten enthalten. Diese Dateien kann man wunderbar an Emails dranhängen, oder aber als Export + Import zwischen verschiedenen Programmen (Outlook, Thunderbird, Mac OS X Addressbook etc) nutzen. Als Premium-Mitglied bei Xing kann man alle seine Kontakte dort auch exportieren und in die oben genannten Applikationen oder auch in sein Handy importieren.

Wie sieht eine VCard aus? Ungefähr so:

BEGIN:VCARD
VERSION:3.0
N:Kliewe;Michael
FN:Michael Kliewe
ADR;TYPE=HOME,WORK:;;Am Stadtgarten 8a;Oelde;;59302
EMAIL;TYPE=HOME;TYPE=WORK:emailadresse@domain.de
EMAIL;TYPE=PREF:wichtige@emailaddresse.de
END:VCARD

Man sieht, das Format ist schon recht alt (1998), heutzutage würde man wahrscheinlich XML wählen. Aber es ist nun mal DER Standard, wir wollen die Adressdaten aus unserer Applikation als VCard exportieren. Dazu gibt es bereits einige vorgefertigte Klassen (Contact_Vcard_Build, PHP vCard Class 2.0, class vcard), die ich aber hier nicht nutzen möchte, da sie entweder das ältere 2.1 Format nutzen oder kein UTF-8 unterstützen. Hier eine einfache Lösung mit wenigen Zeilen Code:

<?php
header("Content-type:text/x-vCard; charset=utf-8");
header("Content-Disposition: attachment; filename=vcardexport.vcf");

$first = "Michael";
$last = "Kliewe";
$email = "emailadresse@domain.de";
?>
BEGIN:VCARD
VERSION:2.1
N:<?php echo($last); ?>;<?php echo($first); ?>
FN:<?php echo($first); ?> <?php echo($last); ?>
EMAIL;PREF;INTERNET:<?php echo($email); ?>
REV:<?php echo date('Y-m-d H:i:s'); ?>
END:VCARD

Das ist natürlich nur der Anfang und ein erster Test. Aber das Prinzip ist recht einfach: Jede Zeile enthält eine Eigenschaft, wie „Voller Name“, „Email-Adresse“, „Wohnadresse“, „Notizen“, „Urls“, „Fotos“, „Firma“, „Geburtstag“ und so weiter. Key und Value sind durch einen Doppelpunkt getrennt, spezielle Optionen wie beispielsweise das oben sichtbare „PREF“ oder „TYPE“ sind via Semikolon getrennt hinzuzufügen. Weitere Informationen erhält man auf der englischen Wikipedia-Seite (die deutsche ist nicht so umfangreich). Man kann auch mehrere Kontakte in einer vcf-Datei exportieren, und objektorientiert mit dem Zend Framework sieht das ganze dann ungefähr so aus:

public function exportvcardAction()
{
	$this->_helper->layout()->disableLayout();
	$this->_helper->viewRenderer->setNoRender();

	$vcardString = '';
	$contacts = $this->service->getAllContacts();
	foreach ($contacts as $contact) {
		/* @var $contact App_Addressbook_Contact */
		$vcardString .= $contact->getContactAsVcardString() . "\r\n";
	}

	if (count($contacts) == 1) {
		$filename = str_replace(" ", "_", $contacts[0]->getFirstname().' '.$contacts[0]->getSurname());
	} else {
		$filename = 'VCARDS';
	}

	$this->getResponse()->setHeader('Content-Type', 'text/x-vCard; charset=utf-8');
	$this->getResponse()->setHeader('Content-Disposition', 'attachment; filename="'.$filename.'.vcf"');
	$this->getResponse()->setHeader('Content-Length', strlen($vcardString));
	$this->getResponse()->setHeader('Connection', 'close');
	$this->getResponse()->setBody($vcardString);
}

Damit werden nun also alle Kontakte iteriert und die einzelnen VCard-Strings aneinandergehängt. Wir nutzen hier die entsprechenden Funktionen, um das Layout und den ViewRenderer zu deaktiveren und alle Informationen ins Response-Objekt zu schreiben
Die Funktion getContactAsVcardString() habe ich so umgesetzt:

public function getContactAsVcardString()
{
	$data['BEGIN'] = 'VCARD';
	$data['VERSION'] = '3.0';
	$data['PRODID'] = '-//company contact export Version 1//EN';
	$data['REV'] = date('Y-m-d H:i:s');
	$data['TZ'] = date('O');

	$data['FN'] = $this->getDisplayName();
	$data['N'] = $this->getSurname().';'.$this->getFirstname();

	if ($this->getTitle() != '') {
		$data['TITLE'] = $this->getTitle();
	}

	foreach ($this->getMailAddresses() as $mailAddress) {
		$data['EMAIL;TYPE=internet'] = $mailAddress;
	}

	if ($this->getNotice() != '') {
		$data['NOTE'] = $this->getNotice();
	}

	$data['END'] = 'VCARD';

	$exportString = '';
	foreach ($data as $index => $value) {
		$exportString .= $index . ':' . $value . "\r\n";
	}

	return $exportString;
}

Als Ergebnis erhält man eine Datei zum Download mit allen $contacts incl. Details.

Written by Michael Kliewe

März 31st, 2010 at 8:44 am

Posted in PHP

Tagged with , , ,

13 Responses to 'Adress- und Kontaktdaten als VCard exportieren'

Subscribe to comments with RSS or TrackBack to 'Adress- und Kontaktdaten als VCard exportieren'.

  1. Danke für den informativen Artikel 🙂 !

    David

    31 Mrz 10 at 13:19

  2. Wie ist das eigentlich, wenn Werte Zeilenumbruchzeichen enthalten. Muss bei der Ausgabe wirklich nichts encodiert werden? Einfach nur rinne?

    Malte

    1 Apr 10 at 11:41

  3. @Malte: Gute Frage, so weit habe ich die RFCs noch nicht gelesen. In meinem Fall werden die bereits vorher herausgefiltert bzw. erst garnicht in die Datenbank gelassen. Bei nahezu allen Feldern außer „NOTE“ machen Umbrüche eh keinen Sinn.

    Michael Kliewe

    1 Apr 10 at 21:51

  4. Hast du sowas auch zufällig für Kalendereinträge (also vcal Dateien) ?

    ragtek

    2 Apr 10 at 11:53

  5. Noch nicht. Aber schau dir mal
    http://pear.php.net/package/File_IMC
    an, damit könntest du eventuell etwas anfangen.

    Michael Kliewe

    3 Apr 10 at 12:41

  6. Tut mir leid, aber ich bin nicht so bewandert in PHP: wie binde ich denn das Script im zweiten Kasten in meine Webseite ein? Kann ich die neue VCF-Datei dasnn auf meiner Webseite verlinken?

    Krissie

    8 Apr 10 at 15:19

  7. @Krissie: Du legst das Script einfach als vcard.php auf deinem Webserver ab und erstellst dann einen Link auf deiner Webseite, a la
    <a href="vcard.php">Meine VCard</a>
    Dann sollte es funktionieren.

    Michael Kliewe

    8 Apr 10 at 21:02

  8. werden auch Felder (Kategorie, Ich suche, Ich biete)exportiert?

    Serge

    25 Jan 11 at 15:17

  9. Danke für die gute Anleitung, geht das Ganze auch andersherum? Also aus einer hochgeladenen Vcard in PHP ein Object erstellen?

    Vielen Dank

    Markus

    2 Aug 12 at 22:02

  10. @Markus Klar geht das, es gibt auch Parser. Hier einen den ich in einem Projekt verwende aus der PEAR Library:
    http://pear.php.net/manual/en/package.fileformats.contact-vcard-parse.intro.php

    Ansonsten einfach mal nach „php vcard parser“ googlen und ausprobieren, es gibt mehr als ein Dutzend mit unterschiedlichstem Featureumfang.

    Michael Kliewe

    2 Aug 12 at 22:29

  11. Danke für den informativen Artikel, besonders der Hinweise auf die englische Wikipedia Seite hat sehr geholfen 😉

    Michael Hack

    31 Okt 13 at 22:07

  12. Hallo
    Habe ein kleine Schwäche im Skript festgestellt:
    Die Einträge werden ohne Zeilenumbruch übergeben, dh. im Texteditor ist alles wunderbar in einer Zeile zu lesen, in Outlook wird dann aber leider ein leerer Kontakt angezeigt!
    Habe es dann in jedes echo am Zeilenende einen Umbruch eingefügt:
    … echo($first).“\n“; …
    Dann wird alles in einzelnen Zeilen dargestellt und Outllook kann die Daten problemlos übernehmen

    georg

    15 Nov 17 at 13:45

  13. Homepage hinzfügen sieht dann wie folgt aus:
    URL;WORK:<?echo $homepage.“\n“;?>

    Georg

    15 Nov 17 at 13:50

Leave a Reply

You can add images to your comment by clicking here.