在解决了基础的ZF2使用DI操作Zend\Mail发送邮件之后,可能我们关注的问题会转移到更加实际的方面,包括:

  • 如何为ZF2中的Zend\Mail设置模板并可以在模板中使用ViewHelper
  • 如何在ZF2中发送带有附件(Attachment)的邮件
  • 如何更好地使用DI来完成这一切

在Zend\Mail中使用模板

首先想到的自然是使用Zend\View作为邮件的模板引擎,这样不但可以使用Zend\View的所有Helper,稍加改进还可以传入整个系统的ServiceLocator让应用范围更广。

那么在庞大的Zend\View中,哪些部分可以构成一个最简的模板引擎呢,我在Zend Framework 2.0的Mvc结构及启动流程分析有过对Zend\View的简单介绍,这里直接说结论,要构建一个最简的ZF2模板引擎,需要:

  1. 一个View\Renderer 渲染器,这里我们选用PhpRenderer,如果你需要整合其他第三方引擎,这里需要自己写对应的View\Renderer
  2. 一个View\Resolver 决策器,因为一个渲染器必须对应一个决策器
  3. 一个ViewModel,用于向模板中放置变量,当然如果你的模板没有变量替换的需求,ViewModel就不是必需的

以上3个部分就可以建立起一个最简的ZF2模板引擎。

在决策器的选择上,ZF2默认的Resolver有三种:

  • Resolver\TemplateMapResolver 以键值对形式指定模板路径,相当于硬编码
  • Resolver\TemplatePathStack 指定若干个目录,然后寻找目录下最可能匹配的模板
  • Resolver\AggregateResolver 其实只是一个队列容器,可以同时支持上述两种Resolver以及用户自定义的Resolver

所以如果每个邮件对应的模板路径都不同,可以直接采用TemplateMapResolver。如果很多模板存放在同一目录下,那么使用TemplatePathStack会更适合,更复杂情况就需要采用AggregateResolver。

以TemplateMapResolver为例,Message与Transport则继续使用ZF2使用DI操作Zend\Mail发送邮件文中的部分:

$view = new Zend\View\Renderer\PhpRenderer();
$resolver = new Zend\View\Resolver\TemplateMapResolver();
$resolver->setMap(array('mailTemplate' => __DIR__ . '/mail/template.phtml'
));
$view->setResolver($resolver);
$viewModel = new Zend\View\Model\ViewModel();
$viewModel->setTemplate('mailTemplate')
->setVariables(array('user' => 'AlloVince'
));$message->setSubject("Zend Mail with Template")
->setBody($view->render($viewModel));
$transport->send($message);

在同一目录下放置模板文件mail/template.phtml。模板的内容为

User : <?=$this->user?> | Url : <?=$this->serverUrl()?>

可以简单的测试变量置入以及Helper的调用。

最后生成邮件:

From: EvaEngine <info@evaengine.com>
To: EvaEngine <allo.vince@gmail.com>
Subject: Zend Mail with Template
User : AlloVince | Url : http://zf2.local

同理如果采用TemplatePathStack,对应的地方修改为

$resolver = new Zend\View\Resolver\TemplatePathStack();
$resolver->setPaths(array('mailTemplate' => __DIR__
));
$viewModel->setTemplate('mail/template');

使用Zend\Mail发送附件

与Zend Framework 1最大的不同,可能就是ZF2中移除了添加附件的方法,改为自己构建一个Zend\Mime\Message然后传入Zend\Mail\Message。笔者以为这个改动不够友好,不过好在MIME规范整体并不复杂。而通过MIME构建邮件内容更加灵活一些。

ZF2对于附件的默认编码是8bit,实测发现8bit编码的附件无法被正确解码,一些图片作为附件后无法正确显示。这个BUG暂时没有时间深究,希望有朋友能告知缘由。

比较保险的做法是对附件采用base64编码,参考下例,附件为同目录下的attachment.jpg:

use Zend\Mime\Message as MimeMessage;
use Zend\Mime\Part;$mimeMessage = new MimeMessage();
$messageText = new Part('Mail Content');
$messageText->type = 'text/html';$data = fopen('attachment.jpg', 'r');
$messageAttachment = new Part($data);
$messageAttachment->type = 'image/jpg';
$messageAttachment->filename = 'attachment.jpg';
$messageAttachment->encoding = Zend\Mime\Mime::ENCODING_BASE64;
$messageAttachment->disposition = Zend\Mime\Mime::DISPOSITION_ATTACHMENT;$mimeMessage->setParts(array($messageText,$messageAttachment,
));$message->setSubject("Mail Subject with Attachment")->setBody($mimeMessage);
$transport->send($message);

发送的邮件为

From: =?utf-8?Q?EvaEngine?= <info@evaengine.com>
To: =?utf-8?Q?EvaEngine?= <allo.vince@gmail.com>
Subject: =?utf-8?Q?Mail=20Subject=20with=20Attachment?=
MIME-Version: 1.0
Content-Type: multipart/mixed;boundary="=_94a850a623ed49ae30132a639054f500"This is a message in Mime Format.  If you see this, your mail reader does not support this format.--=_94a850a623ed49ae30132a639054f500
Content-Type: text/html
Content-Transfer-Encoding: 8bitMail Content
--=_94a850a623ed49ae30132a639054f500
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="attachment"base64code here--=_94a850a623ed49ae30132a639054f500

多个附件与中文文件名

在Windows下,处理文件名中含中文字符的文件需要转换一次编码,在上例中增加:

$file = iconv("UTF-8", "gb2312", '中文文件名.txt');
$data = fopen($file, 'r');
$messageTextAttachment = new Part($data);
$messageTextAttachment->filename = '中文文件名.txt';
$messageTextAttachment->encoding = Zend\Mime\Mime::ENCODING_BASE64;
$messageTextAttachment->disposition = Zend\Mime\Mime::DISPOSITION_ATTACHMENT;$mimeMessage->setParts(array($messageText,$messageAttachment,$messageTextAttachment,
));

就可以同时发送两个附件了。

用DI整合ZF2的邮件模板与附件发送

所有的功能,最终可以用DI整合,方便在系统中复用,有特殊需求的地方复写DI配置文件即可。下面是一个最终完整的例子:

use Zend\Mail\Message;
use Zend\Mail\Transport;
use Zend\Di\Di;
use Zend\Di\Config as DiConfig;
use Zend\Mime\Message as MimeMessage;
use Zend\Mime\Part;$diConfig = array('instance' => array('Zend\View\Resolver\TemplatePathStack' => array('parameters' => array('paths'  => array('mailTemplate' => __DIR__ . '/',),),),'Zend\View\Renderer\PhpRenderer' => array('parameters' => array('resolver' => 'Zend\View\Resolver\TemplatePathStack',),),'Zend\View\Model\ViewModel' => array('parameters' => array('template' => 'mail/template',),),'Zend\Mail\Transport\FileOptions' => array('parameters' => array('path' => __DIR__,)),'Zend\Mail\Transport\File' => array('injections' => array('Zend\Mail\Transport\FileOptions')),'Zend\Mail\Transport\SmtpOptions' => array('parameters' => array('name'              => 'sendgrid','host'              => 'smtp.sendgrid.net','port' => 25,'connectionClass'  => 'login','connectionConfig' => array('username' => 'username','password' => 'password',),)),'Zend\Mail\Message' => array('parameters' => array('headers' => 'Zend\Mail\Headers','Zend\Mail\Message::setTo:emailOrAddressList' => 'allo.vince@gmail.com','Zend\Mail\Message::setTo:name' => 'EvaEngine','Zend\Mail\Message::setFrom:emailOrAddressList' => 'info@evaengine.com','Zend\Mail\Message::setFrom:name' => 'EvaEngine',)),'Zend\Mail\Transport\Smtp' => array('injections' => array('Zend\Mail\Transport\SmtpOptions')),
));$di = new Di();
$di->configure(new DiConfig($diConfig));$transport = $di->get('Zend\Mail\Transport\Smtp');
$view = $di->get('Zend\View\Renderer\PhpRenderer');
$viewModel = $di->get('Zend\View\Model\ViewModel');
$message = $di->get('Zend\Mail\Message');$viewModel->setVariables(array('user' => 'AlloVince'
));$mimeMessage = new MimeMessage();
$messageText = new Part($view->render($viewModel));
$messageText->type = 'text/plain';$messageAttachment = new Part(fopen('attachment.jpg', 'r'));
$messageAttachment->type = 'image/jpg';
$messageAttachment->filename = 'attachment.jpg';
$messageAttachment->encoding = Zend\Mime\Mime::ENCODING_BASE64;
$messageAttachment->disposition = Zend\Mime\Mime::DISPOSITION_ATTACHMENT;$mimeMessage->setParts(array($messageText,$messageAttachment,
));$message->setSubject("Mail Subject")
->setBody($mimeMessage);
$transport->send($message);

Zend\Mail进阶:在ZF2的邮件中使用模板、多个附件以及用DI整合相关推荐

  1. 邮件中的:请看附件;请知悉,英语怎么说。要比较正式的用语

    请看附件:Please refer to the attachment.或 Please refer to the attached. 请知悉:Please be notified. 或 Please ...

  2. 邮件中写html代码规范,EDM电子邮件CSS和HTML编码规范

    EDM是营销过程中比较重要的一种方式,而且在很多软件系统中,也经常会与用户进行电子邮件(Email)的沟通过程.本文档定义了电子邮件(Email)编码规范,便于前端开发工程师为邮件编写HTML模板的时 ...

  3. 使用ZF2的DI操作Zend\Mail发送邮件

    Zend Framework 2完整的实现了DI,也就是依赖注入功能,但是在正式发行的ZF2中,DI已经基本被ServiceManager所取代,一个ZF2项目几乎可以不接触DI这一层. 但是DI仍然 ...

  4. mac mail 删除邮件服务器,如何从Mac OS X中的邮件中删除所有电子邮件 | MOS86

    如果您在Mac上使用Mail应用程序,那么您很可能会定期删除您确定为不必要的垃圾邮件,或者根本不需要这些电子邮件.通常这是一个选择性过程,其中特定的电子邮件消息根据需要被删除,但在某些情况下,您可能需 ...

  5. html设置json请求头,当我想在zf2客户端代码中使用“application/json”时,接受请求标头是“text/html,application/xhtm ...(etc)”...

    我有一个完全可用的API设置,并且zf2客户端I已经在理论上建立了工作,但无论如何,我似乎无法将来自客户端的JSON请求发送到API.每当我测试一下我不断收到以下标题而这又返回406错误:当我想在zf ...

  6. 如果不使用 SQL Mail,如何在 SQL Server 中发送电子邮件

    如果不使用 SQL Mail,如何在 SQL Server 中发送电子邮件 察看本文应用于的产品 文章编号 : 312839 最后修改 : 2006年12月21日 修订 : 10.1 本页 概要 SQ ...

  7. java邮件中添加excel_基于javaMail的邮件发送--excel作为附件

    基于JavaMail的Java邮件发送 Author xiuhong.chen@hand-china.com Desc 简单邮件发送 Date 2017/12/8 项目中需要根据物料资质的状况实时给用 ...

  8. java图片批量添加_java实现邮件中插入批量图片

    首先是MimeMessage这个类,继承于javax.mail.Message,底下还有IMAPMessage.POP3Message.SmartMimeMessage.SMTPMessage等实现, ...

  9. java mail 发送qq以及网易邮件

    1.准备工作:如果是用java mail发送qq邮件 和163邮件 需要注意的地方: (1)qq.163邮箱必须生成授权码才可以发送邮件, 这里使用的QQ邮箱   我们可以在邮箱帮助中找到QQ邮箱的p ...

最新文章

  1. git/github的使用
  2. 看固态存储厂商在硝烟四起的市场中如何发展?
  3. go标准库的学习-errors
  4. (需求实战_03) SpringBoot整合RabbitMQ 关键代码、策略、模式讲解
  5. excel 图片转url_最全总结 | 聊聊 Python 办公自动化之 Excel(下)
  6. java xml特殊字符转义_Java中将xml文件转化为json遇到特殊字符会报错!
  7. zabbix 4.2官方自动监控网络服务端口脚本
  8. windows查看器无法打开图片_Win7自带图片查看器异常
  9. Python基础-序列化(json/pickle)
  10. 黑马程序员 Python学习笔记之 算数运算符
  11. 最后一课——没有拥抱,已成永远
  12. 强连通分量SCC(Tarjan)
  13. 贤内助——ICMP协议
  14. Python(4)print一个10行10列的星星图案
  15. java 调试sql server_sql server 如何调试存储过程
  16. 车牌归属地数据信息sql
  17. VLAN 、PVLAN
  18. matlab 绘制 3d 心
  19. 未在服务器上找到sql安装程序文件,MS SQL Server 2000/以前的某个程序安装已在安装计算机上创建挂起的文件操作。...
  20. python之九九乘法表打印功能深入讲解

热门文章

  1. 用音响里的零件做迷你小机器人_怎么制作迷你避障机器人
  2. python-温度从华氏温度转换为摄氏温度
  3. 怎么实现ABBYY FineReader Pro for Mac的快速激活
  4. 大侠是怎样练成的-周昆
  5. 【veriog】正向计时器设计(FPGA,秒表,时钟,正向计时)
  6. 一元二次函数求解(三角函数、二元一次函数转换为一元二次函数的思路)
  7. Morgan Stanley IT 电面面经 2012.10.11
  8. cocos creator ios回调js代码传入中文参数出现乱码的解决
  9. C语言小项目--三子棋小游戏
  10. GetDC(),ReleaseDC()