1

我正在尝试通过 PHP 生成一个 VCard,然后他们通过电子邮件将其发送给用户。我用硬编码数据编写了一个初始脚本,但最终结果将填写来自 MySQL 的 VCard。

当将 VCard 与合法 VCard(从另一个站点下载并测试)并排查看时,它们看起来几乎相同,但是当我尝试导入生成的 VCard 时,它显示没有数据。实际上,如果我在手机上打开它,它甚至不会识别出它是一张电子名片,而是将我发送到一个损坏的谷歌文档。

我从维基百科借了一些代码来格式化电子名片,一切似乎都很好。您在我的格式中看到任何错误吗?我尝试了不同的换行符 - 无济于事。想法?

这是我的代/邮件的代码:

<?php
$content = "BEGIN:VCARD\r";
$content .= "VERSION:3.0\r";
$content .= "CLASS:PUBLIC\r";
$content .= "FN:Joe Wegner\r";
$content .= "N:Wegner;Joe ;;;\r";
$content .= "TITLE:Technology And Systems Administrator\r";
$content .= "ORG:Wegner Design\r";
$content .= "ADR;TYPE=work:;;21 W. 20th St.;Broadview ;IL;60559;\r";
$content .= "EMAIL;TYPE=internet,pref:__munged__@wegnerdesign.com\r";
$content .= "TEL;TYPE=work,voice:__munged__\r";
$content .= "TEL;TYPE=HOME,voice:__munged__\r";
$content .= "URL:http://www.wegnerdesign.com\r";
$content .= "END:VCARD";

mail_attachment("Joe Wegner.vcf", $content, "__munged__@wegnerdesign.com", "__munged__@wegnerdesign.com", "Wegner Design Contacts", "__munged__@wegnerdesign.com", "Joe Wegner's Contact Info", "");

function mail_attachment($filename, $content, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
        $fileatt_type = "application/octet-stream";

        $headers = "FROM: ".$from_mail;

        $data = chunk_split(base64_encode($content));

        $semi_rand = md5(time());
        $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";

        $headers .= "\nMIME-Version: 1.0\n" .
        "Content-Type: multipart/mixed;\n" .
        " boundary=\"{$mime_boundary}\"";

        $message .= "This is a multi-part message in MIME format.\n\n" .
        "--{$mime_boundary}\n" .
        "Content-Type:text/html; charset=\"iso-8859-1\"\n" .
        "Content-Transfer-Encoding: 7bit\n\n" .
        $message . "\n\n";
        $message .= "--{$mime_boundary}\n" .
        "Content-Type: {$fileatt_type};\n" .
        " name=\"{$filename}\"\n" .
        "Content-Transfer-Encoding: base64\n\n" .
        $data . "\n\n" .
        "--{$mime_boundary}--\n";
        echo "sending message";
        mail($mailto, $subject, $message, $headers);
}
?>

更新1:这让我更加困惑,但也许它会帮助你调试。我已经将我(坏的)生成的 VCard 下载到了我的计算机上,以及从不同网站下载的好的 VCard。正如预期的那样,我生成的一个打开时没有数据,但是好的一个可以正常工作。然后,我创建了第三个扩展名为 .vcf 的空文件,并将我的(坏)文件中的文本复制到该空文件中。我打开了那个文件,所有数据都显示得很完美。为了进一步测试,我将好的 VCard 文件中的文本复制到我的坏文件中,但它仍然打开时没有数据。所以,它似乎是关于编码或我不理解的其他文件的东西。这不是权限 - 这都是相同的。

更新 2:我更改了我的 PHP,以便它会迫使我下载 VCard 以及通过电子邮件发送它。下载的文件打开得很好,所以错误发生在我如何编码(正确的词?)文件,或者 GMail 如何解释它。

更新 3:已修复:想通了。我不确定为什么会这样——因为我在那里找到的所有其他教程都说相反——但有一些关键的变化。首先,我将电子邮件的编码从 base64 更改为 8bit,并将附件内容更改为传递给 email 函数的字符串(因此它是 8bit 格式,而不是 64)。这使得 VCard 在我的桌面上有效且可读。为了让它在我的 android 上读取,我必须将 $fileatt_type 变量更改为“text/x-vcard”,否则 Gmail 会认为它是一个文档。

4

3 回答 3

2

我最近不得不让 vcards 在 android 和 iphone 上工作。我使用了以下函数,它是上面列出的函数的修改版本。这将发送 iphone 上的 gmail 和邮件都可以打开的 vcard。他们也在 Thunderbird 中工作。

function mail_attachment($filename, $content, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
    $fileatt_type = "text/x-vcard";

    $headers = "FROM: ".$from_mail;

    $data = $content;

    $semi_rand = md5(time());
    $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";

    $headers .= "\nMIME-Version: 1.0\n" .
    "Content-Type: multipart/mixed;\n" .
    " boundary=\"{$mime_boundary}\"";

    $message = "This is a multi-part message in MIME format.\n\n" .
    "--{$mime_boundary}\n" .
    "Content-Type:text/html; charset=\"iso-8859-1\"\n" .
    "Content-Transfer-Encoding: 7bit\n\n" .
    $message . "\n\n";
    $message .= "--{$mime_boundary}\n" .
    "Content-Type: {$fileatt_type};\n" .
    " name=\"{$filename}\"\n" .
    "Content-Transfer-Encoding: 8bit\n" .
    "Content-Disposition: attachment;\n" .
    " filename=\"{$filename}\"\n\n" .
    $data . "\n\n" .
    "--{$mime_boundary}--\n";
    //echo "sending message";
    mail($mailto, $subject, $message, $headers);
}
于 2011-10-08T02:27:10.593 回答
1

您在每行的末尾缺少一个 \n 。如果您查看普通的 vCard(例如使用 notepad++),它在每一行的末尾都有一个 CR 和 LF,而您创建的那个只有 CR('\r')。这对我有用:

$content = "BEGIN:VCARD\r\n";
$content .= "VERSION:3.0\r\n";
$content .= "CLASS:PUBLIC\r\n";
$content .= "FN:Joe Wegner\r\n";
$content .= "N:Wegner;Joe ;;;\r\n";
$content .= "TITLE:Technology And Systems Administrator\r\n";
$content .= "ORG:Wegner Design\r\n";
$content .= "ADR;TYPE=work:;;21 W. 20th St.;Broadview ;IL;60559;\r\n";
$content .= "EMAIL;TYPE=internet,pref:joe@wegnerdesign.com\r\n";
$content .= "TEL;TYPE=work,voice:7089181512\r\n";
$content .= "TEL;TYPE=HOME,voice:8352355189\r\n";
$content .= "URL:http://www.wegnerdesign.com\r\n";
$content .= "END:VCARD\r\n";
于 2011-05-31T16:37:49.583 回答
0

我写了一个基于 RFC的vCard 验证器,它可以提供帮助。它不完整,但清理后的文件至少与我尝试过的工具和服务(Gmail、gnokii 和其他一些我不记得的)很好地兼容。HTH。

于 2011-06-01T13:01:01.940 回答