PHP多个附件电子邮件显示为文本

时间:2011-09-12 18:28:51

标签: php email attachment email-attachments

======= UPDATE ======

问题最终是我在使用Content-Type时使用标题ContentType。

感谢您的帮助。

Derp derp derp。

======= / UPDATE =======

我提前为这个令人讨厌的问题道歉。

我正在尝试通过PHP发送带附件的电子邮件。我之前用一个附件成功完成了这项工作。但我无法使用多个附件,或者现在使用此方法使用单个附件。那么,我做错了什么?

据我所知,这些功能还有其他库可用。但我想知道为什么这个不起作用。

以下是生成实际电子邮件的方法:

function gen_mail ()
{
    $files = $this->files();
    $has_attachments = (bool) $files;

    $EOL = "\r\n"; // tried \n, PHP_EOL
    $message = $this->message;

    $headers = $this->gen_headers();
    $headers .= "MIME-Version: 1.0$EOL";

    if ($has_attachments) {
        $hash = md5(time());
        $sep = "=={$hash}==";
        $headers .= "ContentType: multipart/mixed; boundary=\"$sep\"$EOL$EOL";
        $headers .= "This is a MIME-encoded message.$EOL$EOL";
        $headers .= "--$sep$EOL";
    }

    $headers .= "Content-Type: text/html; charset=\"iso-8859-1\"$EOL";
    $headers .= "Content-Disposition: inline$EOL";
    $headers .= "Content-Transfer-Encoding: 7bit$EOL$EOL";
    $headers .= "$message$EOL$EOL";

    if ($has_attachments) { // here go attachments
        foreach ($files as $key => $value) {
            $filename = is_numeric($key)? basename($value) : $key;
            $file = fopen($value, 'rb');
            $data = fread($file, filesize($value));
                            fclose($file);
            $content = chunk_split(base64_encode($data));
            $headers .= "--$sep$EOL";
            $headers .= "Content-Type: application/octet-stream; ";
            $headers .= "name=\"$filename\"$EOL";
            $headers .= "Content-Transfer-Encoding: base64$EOL";
            // tried Content-Disposition, attachment, and every combination
            $headers .= "Content-Description: inline; $EOL ";
            $headers .= "filename=\"$filename\"$EOL$EOL";
            $headers .= "$content$EOL$EOL";
        }
        $headers .= "--$sep--$EOL$EOL";
    }
    return $headers;
}

这就是上面函数返回的标题:

From: test@urbido.es
MIME-Version: 1.0
ContentType: multipart/mixed; boundary="==cd42448edf10bca4640bc7d6365e1961=="

This is a MIME-encoded message.

--==cd42448edf10bca4640bc7d6365e1961==
Content-Type: text/html; charset="iso-8859-1"
Content-Disposition: inline
Content-Transfer-Encoding: 7bit

Travis, you are so cool!!!1!

--==cd42448edf10bca4640bc7d6365e1961==
Content-Type: application/octet-stream; name="html.login.php"
Content-Transfer-Encoding: base64
Content-Description: inline; 
 filename="html.login.php"

PD9waHANCgkNCiRoZWFkZXJfY29uZmlnID0gYXJyYXkoKTsNCiRtc2cgPSAnUmVnaXN0ZXJlZCBP
cGVyYXRvcnMsIGVudGVyIHlvdXIgT3BlcmF0b3IgSUQgYW5kIHBhc3N3b3JkIHRvIGxvZ2luJzsN
CiRtc2dfY2xhc3MgPSAnbm9ybWFsJzsNCmlmICgkbG9nZ2VkX2luKSB7DQoJJGhlYWRlcl9jb25m
aWdbJ2NvbnRyb2xzJ10gPSBhcnJheSAoDQoJCWFycmF5ICgndGV4dCcgPT4gJ1N1Ym1pdCBFbnRy
aWVzJywgJ2hyZWYnID0+ICdlbnRyeScpLA0KCSk7DQoJJG1zZyA9ICdZb3UgYXJlIGxvZ2dlZCBp
bi4gVXNlIHRoZSBhYm92ZSBsaW5rcywgb3IgDQoJCWNsaWNrIDxhIGhyZWY9ImVudHJ5Ij5oZXJl
PC9hPiB0byBiZWdpbiBvciByZXN1bWUgYSBqb2InOw0KCSRtc2dfY2xhc3MgPSAnc3VjY2Vzcyc7
DQp9DQoNCj8+


--==cd42448edf10bca4640bc7d6365e1961==--

我尝试过其他人编写的函数,它们产生看似相同的输出。但是当我发送这些标题时     邮件($ address,$ subject,'',$ headers)

我在收件箱中收到此内容:

This is a MIME-encoded message.

--==cd42448edf10bca4640bc7d6365e1961==
Content-Type: text/html; charset="iso-8859-1"
Content-Disposition: inline
Content-Transfer-Encoding: 7bit

Travis, you are so cool!!!1!

--==cd42448edf10bca4640bc7d6365e1961==
Content-Type: application/octet-stream; name="html.login.php"
Content-Transfer-Encoding: base64
Content-Description: inline;
 filename="html.login.php"

PD9waHANCgkNCiRoZWFkZXJfY29uZmlnID0gYXJyYXkoKTsNCiRtc2cgPSAnUmVnaXN0ZXJlZCBP
cGVyYXRvcnMsIGVudGVyIHlvdXIgT3BlcmF0b3IgSUQgYW5kIHBhc3N3b3JkIHRvIGxvZ2luJzsN
CiRtc2dfY2xhc3MgPSAnbm9ybWFsJzsNCmlmICgkbG9nZ2VkX2luKSB7DQoJJGhlYWRlcl9jb25m
aWdbJ2NvbnRyb2xzJ10gPSBhcnJheSAoDQoJCWFycmF5ICgndGV4dCcgPT4gJ1N1Ym1pdCBFbnRy
aWVzJywgJ2hyZWYnID0+ICdlbnRyeScpLA0KCSk7DQoJJG1zZyA9ICdZb3UgYXJlIGxvZ2dlZCBp
bi4gVXNlIHRoZSBhYm92ZSBsaW5rcywgb3IgDQoJCWNsaWNrIDxhIGhyZWY9ImVudHJ5Ij5oZXJl
PC9hPiB0byBiZWdpbiBvciByZXN1bWUgYSBqb2InOw0KCSRtc2dfY2xhc3MgPSAnc3VjY2Vzcyc7
DQp9DQoNCj8+


--==cd42448edf10bca4640bc7d6365e1961==--

3 个答案:

答案 0 :(得分:0)

你的标题错了。它是“内容处置”,而不是“内容描述”。尝试:

Content-Disposition: attachment; filename="html.login.php"

代替。内容描述是添加附件内容的简短描述,例如“这是我的简历”,并告诉邮件客户端如何处理附件,完全没有任何关系。

答案 1 :(得分:0)

我知道这是一个已经解决的问题,但我希望将来能为所有可能需要它的人发布一个工作函数。 发送多附件电子邮件的网络有很多例子,但大多数都是令人困惑和不工作的。我有turibe功能(我希望你不介意)并重新做一点。

// priority: 1 (Highest), 2 (High), 3 (Normal), 4 (Low), 5 (Lowest).
function mail_attachment($files,$mailto,$from_mail,$from_name,$subject,$message,$bcc=false,$cc=false,$priority="3") {
    $EOL = "\r\n";
    $datetime=new DateTime('now', new DateTimeZone('Europe/Sofia'));
    //sanitize
    $from_mail=filter_var($from_mail, FILTER_SANITIZE_EMAIL);
    $mailto=filter_var($mailto, FILTER_SANITIZE_EMAIL);
    $subject = str_replace(array("\r\n", "\r", "\n", "\t"), '',$subject);
    $from_name = str_replace(array("\r\n", "\r", "\n", "\t"), '',$from_name);
    $bcc = str_replace(array("\r\n", "\r", "\n", "\t"), '',$bcc);
    $cc = str_ireplace(array("\r\n", "\r", "\n", "\t"), '', $cc);


    $headers = "From: ".$from_name." <".$from_mail.">$EOL";
    $headers .= "Message-ID: <".md5(uniqid(microtime()))."@".gethostname().">$EOL";
    $headers .= "Date: ".$datetime->format(DateTime::RFC2822).$EOL;
    $headers .= "X-Mailer: PHP/".phpversion().$EOL;
    $headers .= "X-Sender: ".$_SERVER['REMOTE_ADDR'].$EOL;
    $headers .= "X-Priority: ".$priority.$EOL;
    $headers .= "MIME-Version: 1.0$EOL";
    if($bcc)$headers .= "Bcc:".$bcc."\r\n";
    if($cc)$headers .= "Cc:".$cc."\r\n";

    if($files){
        $message=nl2br(trim(filter_var(stripslashes($message), FILTER_SANITIZE_STRING)));
        $hash = md5(time());
        $sep = "=={$hash}==";
        $headers .= "Content-Type: multipart/mixed; boundary=\"$sep\"$EOL$EOL";
        $headers .= "This is a MIME-encoded message.$EOL$EOL";
        $headers .= "--$sep$EOL";
        $headers .= "Content-Type: text/html; charset=\"iso-8859-1\"$EOL";
        $headers .= "Content-Disposition: inline$EOL";
        $headers .= "Content-Transfer-Encoding: 7bit$EOL$EOL";
        $headers .= "$message$EOL$EOL";

        //here go attachments
        foreach ($files as $key => $value) {
            $filename = is_numeric($key)? basename($value) : $key;
            $file = fopen($value, 'rb');
            $data = fread($file, filesize($value));
            fclose($file);
            $content = chunk_split(base64_encode($data));
            $headers .= "--$sep$EOL";
            $headers .= "Content-Type: application/octet-stream; ";
            $headers .= "name=\"$filename\"$EOL";
            $headers .= "Content-Transfer-Encoding: base64$EOL";
            $headers .= "Content-Description: inline; $EOL ";
            $headers .= "filename=\"$filename\"$EOL$EOL";
            $headers .= "$content$EOL$EOL";
        }
        $headers .= "--$sep--$EOL$EOL";
    }else{
        $message=trim(filter_var(stripslashes($message), FILTER_SANITIZE_STRING));
    }

    $r=mail($mailto, $subject, $message, $headers);

   return $r;
}

答案 2 :(得分:0)

我使用共享主机并且无法弄清楚如何使用PEAR邮件功能 - 我读过的所有内容似乎都假设读者已经知道如何将PEAR与include('Mail.php')结合起来) - 但没有人说如何获取Mail.php文件。 Urgh。

无论如何,我的应用程序不经常发送电子邮件,一次只发送给少数收件人。所以我觉得使用php的邮件工具很好。

此外,有时我的附件是动态生成的,所以我将chunk_split放在方法之外,这样我就可以轻松附加实际文件,或者像生成数据一样轻松生成数据并将其作为文件附加。

这是一个实际经过测试的简单电子邮件类:

<?php
class MyMail  {  

private function getMimeType ($fileName) {  
    $mime_types = array("pdf"=>"application/pdf","zip"=>"application/zip","csv"=>"text/plain","doc"=>"application/msword"
            ,"docx"=>"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
            ,"xls"=>"application/vnd.ms-excel","xlsx"=>"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
            ,"ppt"=>"application/vnd.ms-powerpoint","pptx"=>"application/vnd.openxmlformats-officedocument.presentationml.presentation"
            ,"gif"=>"image/gif","png"=>"image/png","jpeg"=>"image/jpg","jpg"=>"image/jpg","mp3"=>"audio/mpeg","wav"=>"audio/x-wav"
            ,"mpeg"=>"video/mpeg","mpg"=>"video/mpeg","mpe"=>"video/mpeg","css"=>"text/css","js"=>"application/javascript"
            ,"php"=>"text/plain","htm"=>"text/html","html"=>"text/html","txt"=>"text/plain");  
    $extension = explode('.',$fileName);
    $extension = end($extension);
    $extension = strtolower($extension);

    if(isset($mime_types[$extension]))
        return $mime_types[$extension];

    return "application/octet-stream";
}

private $to = '';
private $subject = '';
private $returnPath = '';
private $attachments = array();
private $recipients = array('from' => '', 'reply' => ''); 
private $message = '';


public function setTo($s)  {  // comma separated list
    $this->to = $s;  
}   
public function setSubject($s)  {  
    $this->subject = $s;  
}   
public function setFrom($s)  {  // one email address only!
    $this->recipients['from'] = "From: $s";  
} 
public function setReturnPath($s)  {  // one email address only!
    $this->returnPath = "-r $s";  
}   
public function setReplyTo($s)  {  
    $this->recipients['reply'] = "Reply-To: $s";  
}   
public function setCc($s)  { // comma separated list 
    $this->recipients['cc'] = "Cc: $s";  
}
public function setBcc($s)  {  // comma separated list 
    $this->recipients['bcc'] = "Bcc: $s";  
}   
public function setMessage($s)  {  // be carefull to include strategic nl and spaces for text only presentation -- which uses strip_tags()
    $this->message = $s;  
}   
public function setAttachment($fileName, $data)  {  
    $this->attachments[] = array('name' => $fileName, 'data' => $data);
}

public function send() {

    $attachments = ( count($this->attachments) > 0 );

    $altMarker = '===_Alt_BOUNDRY_' . md5(uniqid(time()));
    $mixedMarker = str_replace('Alt', 'Mixed', $altMarker); 


    $txtMsg = strip_tags($this->message);

    $htmlMsg = "<!DOCTYPE html>\n<html>\n<head>\n"; 
    $htmlMsg .= '<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">';
    $htmlMsg .= "\n</head>\n<body>\n";
    $htmlMsg .= $this->message;
    $htmlMsg .= "\n</body>\n</html>";


    $h = array();

    preg_match('/<([^<>]+)>$|^\bFrom: ([^<>]+)\b$/',$this->recipients['from'], $a);

    $nakedFrom = !empty($a[1]) ? $a[1] : $a[2];


    if( empty($this->returnPath) )
        $this->returnPath = '-r ' . $nakedFrom;

    if( empty($this->recipients['reply']) )
        $this->recipients['reply'] = 'Reply-To: ' . str_replace('From: ','',$this->recipients['from']);



    foreach ($this->recipients as $v)
        $h[] = $v;

    $h[] = "MIME-Version: 1.0";

    if( $attachments ) {
        $h[] = 'Content-Type: multipart/mixed; boundary="' . $mixedMarker . '"';
        $h[] = '';
        $h[] = '--' . $mixedMarker;
    }
    $h[] = 'Content-Type: multipart/alternative; boundary="' . $altMarker . '"';
    $h[] = '';
    $h[] = '--' . $altMarker;
    $h[] = 'Content-Type: text/plain; charset=iso-8859-1';
    $h[] = 'Content-Transfer-Encoding: 7bit';
    $h[] = '';
    $h[] = $txtMsg;
    $h[] = '--' . $altMarker;
    $h[] = 'Content-Type: text/html; charset=iso-8859-1';
    $h[] = 'Content-Transfer-Encoding: 7bit';
    $h[] = '';
    $h[] = $htmlMsg;
    $h[] = '--' . $altMarker . '--';
    $h[] = '';

    foreach( $this->attachments as $v ) {
        $h[] = '--' . $mixedMarker;
        $h[] = 'Content-Type: ' . $this->getMimeType ($v['name']) . ';';
        $h[] = '    name="' . $v['name'] . '"';
        $h[] = 'Content-Transfer-Encoding: base64';
        $h[] = 'Content-Disposition: attachment;';
        $h[] = '    filename="' . $v['name'] . '"';
        $h[] = ''; /* skip */
        $h[] = $v['data'];
    }

    if( $attachments ) 
        $h[] = '--' . $mixedMarker . '--';

    return (mail( $this->to, $this->subject, null, implode("\r\n", $h ), $this->returnPath) ? true : false); 
}

}


* - 使用:*

$mail = new MyMail;  
$mail->setSubject( ' Testing 123 Subject' );
$mail->setFrom( 'me <testFrom@abc.com>' ); 
$mail->setTo( 'Anne Test <atest@example.com>' );
$mail->setCc('Jeff Test <jtest@example.com>, Mary Test <mtest@example.com>');
$mail->setMessage( "<h1>This is a test</h1>\n\n<p>This is a para</p>" ); // note the nl added in case mail opens as pure text...

// dynamically produced file data  
$mail->setAttachment( $fileName1,  
    chunk_split(base64_encode($attachmentData1)) );  

// attach actual file  
$mail->setAttachment( $fileName2,  
    chunk_split(base64_encode(file_get_contents('testFile.pdf'))) );   

echo ( $mail->send() ) ? 'sent' : 'oops';