2012-11-08 46 views
5

我在當前項目中使用此PHP IMAP類:http://code.google.com/p/php-imap/source/browse/trunk/ImapMailbox.php。經過一些修改後,班級正在工作。但是,無論何時下載.docx文件,它們總是被損壞並且必須由辦公室恢復。使用PHP IMAP類時損壞的.docx文件

protected function initMailPart(IncomingMail $mail, $partStruct, $partNum) { 
    $data = $partNum ? $this->imap_fetchbody($this->mbox, $mail->mId, $partNum, FT_UID) : $this->imap_body($this->mbox, $mail->mId, FT_UID); 

    if($partStruct->encoding == 1) { 
     $data = $this->imap_utf8($data); 
    } 
    elseif($partStruct->encoding == 2) { 
     $data = $this->imap_binary($data); 
    } 
    elseif($partStruct->encoding == 3) { 
     $data = $this->imap_base64($data); 
    } 
    elseif($partStruct->encoding == 4) { 
     $data = $this->imap_qprint($data); 
    } 
    $data = trim($data); 

    $params = array(); 
    if(!empty($partStruct->parameters)) { 
     foreach($partStruct->parameters as $param) { 
      $params[strtolower($param->attribute)] = $param->value; 
     } 
    } 
    if(!empty($partStruct->dparameters)) { 
     foreach($partStruct->dparameters as $param) { 
      $params[strtolower($param->attribute)] = $param->value; 
     } 
    } 
    if(!empty($params['charset'])) { 
     $data = iconv($params['charset'], $this->serverEncoding, $data); 
    } 

    // attachments 
    if($this->attachmentsDir) { 
     $filename = false; 
     $attachmentId = $partStruct->ifid ? trim($partStruct->id, " <>") : null; 
     if(empty($params['filename']) && empty($params['name']) && $attachmentId) { 
      $filename = $attachmentId . '.' . strtolower($partStruct->subtype); 
     } 
     elseif(!empty($params['filename']) || !empty($params['name'])) { 
      $filename = !empty($params['filename']) ? $params['filename'] : $params['name']; 
      $filename = $this->decodeMimeStr($filename); 
      $filename = $this->quoteAttachmentFilename($filename); 
     } 
     if($filename) { 
      if($this->attachmentsDir) { 
       $filepath = rtrim($this->attachmentsDir, '/\\') . DIRECTORY_SEPARATOR . $filename; 
       file_put_contents($filepath, $data); 
       $mail->attachments[$filename] = $filepath; 
      } 
      else { 
       $mail->attachments[$filename] = $filename; 
      } 
      if($attachmentId) { 
       $mail->attachmentsIds[$filename] = $attachmentId; 
      } 
     } 
    } 
    if($partStruct->type == 0 && $data) { 
     if(strtolower($partStruct->subtype) == 'plain') { 
      $mail->textPlain .= $data; 
     } 
     else { 
      $mail->textHtml .= $data; 
     } 
    } 
    elseif($partStruct->type == 2 && $data) { 
     $mail->textPlain .= trim($data); 
    } 
    if(!empty($partStruct->parts)) { 
     foreach($partStruct->parts as $subpartNum => $subpartStruct) { 
      $this->initMailPart($mail, $subpartStruct, $partNum . '.' . ($subpartNum + 1)); 
     } 
    } 
} 

protected function decodeMimeStr($string, $charset = 'UTF-8') { 
    $newString = ''; 
    $elements = $this->imap_mime_header_decode($string); 
    for($i = 0; $i < count($elements); $i++) { 
     if($elements[$i]->charset == 'default') { 
      $elements[$i]->charset = 'iso-8859-1'; 
     } 
     $newString .= iconv($elements[$i]->charset, $charset, $elements[$i]->text); 
    } 
    return $newString; 
} 
+0

仔細檢查附件格式。這些文檔是否總是通過特定的電子郵件客戶端(例如Microsoft Outlook?)附加。 – hakre

+0

他們肯定是從office 2007保存的.docx,從Gmail,Outlook 2007和Hotmail發送電子郵件時也是如此。 – Chardard

+0

很高興知道!你可以創建一個MD5校驗和之前,然後之後?文件大小也有所不同嗎?此外,我會用不同的編碼保存多個版本的文件,僅用於測試目的。我會在那裏聞到一些東西,但很自然地很難說只是快速掃描代碼。你對空的字符集做出了一些決定,可能這裏有一些抽搐。 – hakre

回答

1

嘗試使用一個好的編輯器在IMAP往返之前和之後進入二進制文件,看看是否有明顯的東西。我遇到類似的問題,其中空白進入PHP腳本(例如,在關閉?>標記之後的文件末尾);大多數格式不會閃爍,但.docx可能會在最後留下空白時被踢入恢復狀態。