2011-10-18 48 views
1

我使用Zend的Zend_Mail_Storage_Pop3连接到邮件服务器,打开电子邮件并遍历其附件。如果附件是PDF,我需要下载它。在每个消息部分的每次迭代中,我调用getHeaders并使用Regex来确定附件的MIME类型。在大多数情况下,我得到的是这样的:PHP:如何确定电子邮件附件的MIME类型?

["content-type"]=> string(64) "application/octet-stream; name=abc.pdf" 
["content-transfer-encoding"]=> string(6) "base64" 

但在某些情况下,我得到的是这样的:

multipart/mixed; boundary=--boundary_2_1dca5b3b-499e-4109-b074-d8b5f914404a 

如何确定这些附件的MIME类型?

+0

它可以是你所遇到的。着名的Microsoft TNEF附件格式?(http://en.wikipedia.org/wiki/Transport_Neutral_Encapsulation_Format) – iWantSimpleLife

+1

看起来像'Zend_Ma il_Storage_Pop3'无法解析电子邮件。您可能想要使用Mailparse扩展名:http://php.net/manual/en/book.mailparse.php或Imap扩展名http://www.php.net/manual/en/book.imap.php – hakre

+0

我发布了一篇相当长的关于如何解析原始邮件以查找部件的解释,但扩展可能是一个很好的起点。你可以看看'php-mime-mailparser':http://code.google.com/p/php-mime-mail-parser/ – Andrew

回答

0

这是一个复杂的案例。当content-typemultipart/mixed这意味着有几个电子邮件。其中一个或多个可能是附件(除了可能包括html区域或纯文本)。

content-typemultipart/mixed时,也给出边界。您可以使用此正则表达式来确定,如果你正在处理一个多部分电子邮件:

$contentType = $this->GetHeader('content-type'); 
$regex = '%multipart.*?boundary\s*=\s*"?(\w+)?"?%is'; 
$matches = array(); 

if (preg_match($regex, $contentType, $matches)) { 
    $this->isMultiPart = true; 
    $this->boundary = $matches[1]; 
} else { 
    $this->isMultiPart = false; 
} 

(注意,这个样本是一个较大的类地处理电子邮件消息的一部分)

如果你的消息是多部分电子邮件,下一步是分离所有的部分。你可以这样做,像这样:

$parts = explode("--$this->boundary", $this->fullBody); 

边界始终将--每电子邮件标准开始。然后唯一要做的就是解析每个单独的部分。
你可能已经有了这样的代码。每个部分都有与您在问题中提到的相同的标题:content-typecontent-transfer-encoding
也可能有其他部分标题,并且您将要删除它们(如果我没有记错,它们都将以前缀content开头)。
然后确定,如果部分是base64编码,你考虑的是(你可以检查content-transfer-encoding头,以确定这一点。
MIME类型的各个附件将被存储在部分的content-type头就像在箱单部分消息的

一个音符。 - 这个假设您正在处理的消息的原始来源要做到这一点,你可以使用getRawHeadergetRawContent

+0

嗨,Andrew,Zend库公开了一个'isMultipart()'方法。我用它来确定电子邮件是否可能有附件。我开始在* second *'Zend_Mail_Message'部分循环(因为我认为*是附件开始的地方;第一部分是实际的电子邮件)。这是正确的吗? – StackOverflowNewbie

+0

'fullBody'是Zend方法吗?我想尝试你的解决方案。 – StackOverflowNewbie

+0

一般是这样做的方式,但它似乎像你的情况有一个在Zend Framework的某种错误。从你说的话,好像'isMultipart()'是'返回TRUE',但随后一旦你看看消息部分它仍然说,这是多。 所以基本上,无论是返回'多/ mixed'应如上分析,这将(希望!)给你的各个部分。 – Andrew