【问题标题】:Formatting VCard in PHP在 PHP 中格式化 VCard
【发布时间】:2011-09-05 14:57:58
【问题描述】:

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

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

我从 wikipedia 借了一些代码来格式化 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 会认为它是一个文档。

【问题讨论】:

  • 您使用什么 ide?有时我会遇到与 php 文件编码方式相关的“编码”问题。这通常发生在我编辑用 mac 创建的 php 文件时。
  • 我在 vim 中编辑。据我所知,没有任何方法可以更改那里的编码内容,尽管这听起来可能与我的问题相似。

标签: php email vcf-vcard email-headers


【解决方案1】:

我最近不得不让 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);
}

【讨论】:

    【解决方案2】:

    您在每行的末尾缺少一个 \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";
    

    【讨论】:

    • 复制并粘贴您的代码,但我仍然没有任何运气。如果您查看我的最新更新,看起来错误不在于文件的文本,而在于文件本身的结构(如果这有意义的话.. 不是这方面的专家)。
    • 我已经用 Outlook 测试了代码,它对我有用,你的第一次更新非常有意义,因为当你在记事本中复制/粘贴时,它会添加 LF(事实上这对我来说也很有效!)。很高兴你解决了它!P.S. (我正在下载 VCf 并将其导入到 Outlook 中进行测试)
    【解决方案3】:

    我根据 RFC 写了一个 vCard validator,这可能会有所帮助。它不完整,但清理后的文件至少与我尝试过的工具和服务(Gmail、gnokii 和其他一些我不记得的)很好地兼容。 HTH。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-19
      • 1970-01-01
      • 2017-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多