send email with attached files in ZF2

2019-04-26 15:42发布

How to send email with text/plain, text/html and attaches in zf2 ? I use this code to send email with smtp:

$files = $this->params()->fromFiles();
$smtp = new \Zend\Mail\Transport\Smtp();
$smtp->setAutoDisconnect(true);
$optn = new \Zend\Mail\Transport\SmtpOptions(array(
    'host'              => 'mail.myserver.com',
    'connection_class'  => 'login',
    'connection_config' => array(
        'username' => 'user@myserver.com',
        'password' => 'mypassword',
    ),
));
$smtp->setOptions($optn);


$htmlPart = new \Zend\Mime\Part('<p>some html</p>');
$htmlPart->type = Mime::TYPE_HTML;

$textPart = new \Zend\Mime\Part('some text');
$textPart->type = Mime::TYPE_TEXT;

$i=0;
$attaches = array();
foreach($files as $file){
    if ($file['error'])
        continue;
    $attaches[$i] = new \Zend\Mime\Part(file_get_contents($file['tmp_name']));
    $attaches[$i]->type = $file['type'].'; name="'.$file['name'].'"';
    $attaches[$i]->encoding = 'base64';
    $attaches[$i]->disposition = 'attachment';
    $attaches[$i]->filename = $file['name'];
    $i++;
}

$parts = array();
if (count($attaches)>0) {
    $parts = array_merge(array($textPart,$htmlPart),$attaches);
    $type = Mime::MULTIPART_MIXED;
}
else{
    $parts = array($textPart, $htmlPart);
    $type = Mime::MULTIPART_ALTERNATIVE ;
}
$body = new \Zend\Mime\Message();
$body->setParts($parts);

$message = new \Zend\Mail\Message();
$message->setFrom('user@myserver.com');
$message->addTo('receiver@myserver.com');
$message->setSubject('subject');
$message->setEncoding("UTF-8");
$message->setBody($body);
$message->getHeaders()->get('content-type')->setType($type);

$smtp->send($message);

If I attach files, it sends files and contents but it shows plain and html text together in receiver inbox:

<p>some html</p>
some text

When I don't attach any files, it shows html text singly:

some html

Any help?

4条回答
家丑人穷心不美
2楼-- · 2019-04-26 15:52

Set the type from :

$attaches[$i]->type = $file['type'].'; name="'.$file['name'].'"';

To:

$attaches[$i]->type = \Zend\Mime\Mime::TYPE_OCTETSTREAM;

You will also want to confirm that if you are using an SMTP service that they allow attachements through the protocol.

查看更多
时光不老,我们不散
3楼-- · 2019-04-26 16:05

E-Mail Messages with Attachments

$mail = new Zend\Mail\Message();
// build message...
$mail->createAttachment($someBinaryString);
$mail->createAttachment($myImage,
                        'image/gif',
                        Zend\Mime\Mime::DISPOSITION_INLINE,
                        Zend\Mime\Mime::ENCODING_BASE64);

If you want more control over the MIME part generated for this attachment you can use the return value of createAttachment() to modify its attributes. The createAttachment() method returns a Zend\Mime\Part object:

$mail = new Zend\Mail\Message();

$at = $mail->createAttachment($myImage);
$at->type        = 'image/gif';
$at->disposition = Zend\Mime\Mime::DISPOSITION_INLINE;
$at->encoding    = Zend\Mime\Mime::ENCODING_BASE64;
$at->filename    = 'test.gif';

$mail->send();

An alternative is to create an instance of Zend\Mime\Part and add it with addAttachment():

$mail = new Zend\Mail\Message();

$at = new Zend\Mime\Part($myImage);
$at->type        = 'image/gif';
$at->disposition = Zend\Mime\Mime::DISPOSITION_INLINE;
$at->encoding    = Zend\Mime\Mime::ENCODING_BASE64;
$at->filename    = 'test.gif';

$mail->addAttachment($at);

$mail->send();

Reference1 Reference2 Reference3

查看更多
Evening l夕情丶
4楼-- · 2019-04-26 16:08

I have found it a better solution so I am writing it.

Namespace YourNamesapace;

use Zend\Mail\Message as ZendMessage;
use Zend\Mime\Part as MimePart;
use Zend\Mime\Message as MimeMessage;
use Zend\Mail\Transport\Sendmail;
class Testmail
{
    public static function sendMailWithAttachment($to, $subject, $htmlMsg, $dir, $fileName)
    {
        $fileFullPath = $dir . '/' . $fileName;
        // Render content from template
        $htmlContent = $htmlMsg;
        // Create HTML part
        $htmlPart = new MimePart($htmlContent);
        $htmlPart->type = "text/html";
        // Create plain text part
        $stripTagsFilter = new \Zend\Filter\StripTags();
        $textContent = str_ireplace(array("<br />", "<br>"), "\r\n", $htmlContent);
        $textContent = $stripTagsFilter->filter($textContent);
        $textPart = new MimePart($textContent);
        $textPart->type = "text/plain";

        // Create separate alternative parts object
        $alternatives = new MimeMessage();
        $alternatives->setParts(array($textPart, $htmlPart));
        $alternativesPart = new MimePart($alternatives->generateMessage());
        $alternativesPart->type = "multipart/alternative;\n boundary=\"".$alternatives->getMime()->boundary()."\"";

        $body = new MimeMessage();
        $body->addPart($alternativesPart);


        $attachment = new MimePart( file_get_contents($fileFullPath) );
        $attachment->type = \Zend\Mime\Mime::TYPE_OCTETSTREAM;
        $attachment->filename = basename($fileName);
        $attachment->disposition = \Zend\Mime\Mime::DISPOSITION_ATTACHMENT;
        $attachment->encoding = \Zend\Mime\Mime::ENCODING_BASE64;
        $body->addPart($attachment);
        // Create mail message
        $mailMessage = new ZendMessage();
        $mailMessage->setFrom('noreply@example.com', 'from Name');
        $mailMessage->setTo($to);
        $mailMessage->setSubject($subject);
        $mailMessage->setBody($body);
        $mailMessage->setEncoding("UTF-8");
        $mailMessage->getHeaders()->get('content-type')->setType('multipart/mixed');
        $transport = new Sendmail();
        $transport->send($mailMessage);
    }
}

Reference: http://resoftsol.com/sending-e-mail-with-alternative-parts-plus-attachments/

查看更多
Luminary・发光体
5楼-- · 2019-04-26 16:19

Currently there is no easy way in ZF2 (2.2) to combine a multipart/alternative body (html with text alternative for clients that cannot/do-not-want-to use html) with attachments. If you add the 'multipart/alternative' content-type header to the entire message, in some email clients the attachment (link) will not be displayed.

The solution is to split the message in two, the body (text and html) and the attachment:

http://jw-dev.blogspot.com.es/2013/01/zf2-zend-mail-multipartalternative-and.html

an example:

        $content  = new MimeMessage();
        $htmlPart = new MimePart("<html><body><p>Sorry,</p><p>I'm going to be late today!</p></body></html>");
        $htmlPart->type = 'text/html';
        $textPart = new MimePart("Sorry, I'm going to be late today!");
        $textPart->type = 'text/plain';
        $content->setParts(array($textPart, $htmlPart));

        $contentPart = new MimePart($content->generateMessage());        
        $contentPart->type = 'multipart/alternative;' . PHP_EOL . ' boundary="' . $content->getMime()->boundary() . '"';

        $attachment = new MimePart(fopen('/path/to/test.pdf', 'r'));
        $attachment->type = 'application/pdf';
        $attachment->encoding    = Mime::ENCODING_BASE64;
        $attachment->disposition = Mime::DISPOSITION_ATTACHMENT;

        $body = new MimeMessage();
        $body->setParts(array($contentPart, $attachment));

        $message = new Message();
        $message->setEncoding('utf-8')
        ->addTo('mywife@home.com')
        ->addFrom('myself@office.com')
        ->setSubject('will be late')
        ->setBody($body);

        $transport = new SmtpTransport();
        $options   = new SmtpOptions($transportConfig),
        ));

        $transport->setOptions($options);
        $transport->send($message);

For the above you would need the following use statements:

use Zend\Mail\Message;
use Zend\Mail\Transport\Smtp as SmtpTransport;
use Zend\Mail\Transport\SmtpOptions;
use Zend\Mime\Mime;
use Zend\Mime\Part as MimePart;
use Zend\Mime\Message as MimeMessage;

ZF1 had a _buildBody() method in Zend_Mail_Transport_Abstract which did this automatically.

查看更多
登录 后发表回答