【问题标题】:How to serve multipart/related content in PHP?如何在 PHP 中提供多部分/相关内容?
【发布时间】:2010-12-20 09:30:51
【问题描述】:

说,我有一个 application/xhtml+xml 内容和一个 gif 图像。如何在单个 http get 请求(使用 PHP)中服务(而不是呈现)这两个?它应该是一个 multipart/related 内容。看了this RFC之后,我尝试了一些东西;但它没有用。 (不,我不是要发送带有附件的电子邮件)

提前致谢。

编辑:最后我成功了。我认为,如果我写下我是如何做到的,那将会很有用。我已将此添加为答案。请往下看。

【问题讨论】:

    标签: php mime


    【解决方案1】:

    这是[为我工作](不,我没有使用 PHPMailer;可能有用,但我无法使其工作):

    // Two contents : application/xhtml+xml and image/gif
    // Here we go
    <?php
        $boundary = "ghorar#deem";
        $im_len = filesize("path/to/abc.gif")
        header("Content-Type:multipart/related; boundary=\"$boundary\"; type=\"application/xhtml+xml\"");
        $xml_cnt = <<<EOD
    <media xmlns="http://www.sth.com/sth.xsd">
        <objectURI>cid:112509abc@syz.com</objectURI>
        <size>$im_len</size>
        <type>image/gif</type>
        <name>abcxyz</name>     
        <description>blah blah</description>
    </media>
    EOD;
        $xml_len = strlen($xml_cnt);        
        $im = imagecreatefromgif("path/to/abc.gif");
        $to_send = "This is a multi-part message example in MIME format
    
    --$boundary
    Content-Type: application/xhtml+xml;
    Content-ID: <e4509xml@asd.com>
    Content-Length: $xml_len
    
    $xml_cnt
    --$boundary
    Content-Type: image/gif;
    Content-ID: <112509abc@syz.com>
    Content-Length: $im_Len
    Content-Transfer-Encoding: binary
    
    ";
        echo $to_send;
        imagegif($im);
        echo "\r\n--$boundary--";
        imagedestroy($im);
    ?>
    

    您也可以从文件中加载 xml。但是,请注意,如果您的 xml 引用图像(就像我在这里所做的那样),您需要使用它的 Content-ID 来引用它。另外,请注意图像的 Content-ID 字段中的“”字符(在边界之后)和引用位置的“cid:”符号。它对我有用。感谢 Carlos Lima 为我花时间。

    【讨论】:

      【解决方案2】:

      我一直在努力实现同样的目标。

      似乎 MSIE 是目前唯一支持 multipart/related 本机的浏览器(Opera 可能有一些支持 - 但我没有玩过它)但是在加载此类文件时,它似乎完全忽略了有关的 HTTP 标头mime 类型和其他内容(例如缓存信息、处置等)。事实上,MSIE 只会在 URL 具有 .mht 文件扩展名的情况下打开文件(即它违反了大多数关于 HTTP 的规则)。

      此外,MSIE 将愉快地加载任何包含嵌入式多部分/相关文件(前提是它被编码为纯文本),而不呈现附件包含的数据。看起来处理这些文件的功能是允许查看文件的快速破解

      如果您重新配置您的网络服务器以使用 php 解析 .mht 网址(或使用 mod_rewrite 重新映射网址),那么您可能会发现它可能会工作(尽管我不希望它与附加的查询字符串)。但是,如果您正在生成动态内容,则可能会出现问题(它不会在您期望的时候从缓存/刷新中过期)。

      长话短说-它不起作用。

      【讨论】:

      • 我为移动浏览器工作,而不是为普通的桌面浏览器工作。效果很好。
      • phpclasses 上有一些代码应该分解一个 mhtml 文件 - 但它对我不起作用:(
      【解决方案3】:

      恐怕你不能达到你想要的目的。

      据我所知,如果您想这样做以提供网页,浏览器将无法使用此类 MIME 响应来呈现页面。

      如果您想了解此邮件的工作原理,请给自己发送一封带有附件的电子邮件,然后在您的电子邮件客户端(不是网络邮件)上转到电子邮件正文上的“查看源代码”选项。

      您将使用 MIME 多部分编码在同一邮件中看到您的邮件、附件和可能的其他部分。

      OTOH,如果您希望它发送电子邮件,可以使用 PHPMailer 等库为您完成所有编码。
      如果这是您想要的,请在他们的网站上查看this example

      编辑:

      您可以使用 PHPMailer 来构建消息,然后只使用结果,而不是实际发送电子邮件。

      试试这样的:

      ** 这是未经测试的代码,仅供参考**

      <?php
        require_once('../class.phpmailer.php');
        $mail = new PHPMailer(true); // the true param means it will throw exceptions on     errors, which we need to catch
      
        try {
          $mail->MsgHTML(file_get_contents('contents.html'));
          $mail->AddAttachment('images/phpmailer.gif');      // attachment
          $mail->AddAttachment('images/phpmailer_mini.gif'); // attachment
          $mime_message = $mail->CreateBody();
          echo $mime_message;
        } catch (phpmailerException $e) {
          echo $e->errorMessage(); //Pretty error messages from PHPMailer
        } catch (Exception $e) {
          echo $e->getMessage(); //Boring error messages from anything else!
        }
      ?>
      

      【讨论】:

      • 但是必须有一种方法来提供多部分/相关文档,不是吗?否则如何实现 this(rfc-archive.org/getrfc.php?rfc=2387)?
      • 您可以“提供”它,就像输出 MIME 多部分消息一样,但正如我所说,我认为没有浏览器会按照您期望的方式呈现它。
      • 换句话说,如果你想要的是提供一个网页,不,它不会工作。如果您想要输出一个多部分文档以供其他东西(如邮件客户端或其他东西)使用/呈现,是的,您可以。
      • 我尝试回显,但没有成功。 PHP header() 调用的“内容类型”应该是什么?它应该只“多部分/相关”吗?我应该使用不同的内容类型调用 header() 3 次吗?或者,只需一个 header() 调用并回显其余部分?
      • 我将添加一个示例,只需一分钟
      猜你喜欢
      • 2017-04-21
      • 2016-08-01
      • 2018-11-20
      • 1970-01-01
      • 2012-05-26
      • 2018-01-22
      • 2014-03-08
      • 1970-01-01
      • 2015-09-13
      相关资源
      最近更新 更多