原文发表在个人我的网站:利用 Composer 完善本身的 PHP 框架(二)——发送邮件php
本教程示例代码见 https://github.com/johnlui/My-First-Framework-based-on-Composerhtml
上一篇文章中,咱们手工建造了一个简易的视图加载器,顺便引入了错误处理包,让咱们的 MFFC 框架在 M、V、C 三个方面都达到了“好用”的水平。View 是一个可插拔组件,在本篇文章中咱们要建立另外一个可插拔组件——邮件发送模块。git
咱们采用 nette/mail
包做为咱们的邮件发送基础模块,在它的基础上封装一个 Mail
类,暴露出简洁的 API 给控制器使用,下面咱们正式开始。github
引入 nette/mail
包,修改 composer.json
:json
"require": { "codingbean/macaw": "dev-master", "illuminate/database": "*", "filp/whoops": "*", "nette/mail": "*" },
运行 composer update
,等待安装完成。nette/mail
的文档位于:http://doc.nette.org/en/2.2/mailing 让咱们阅读它,而后设计 Mail 类:数组
新建 services/Mail.php
文件,内容以下:缓存
<?php use Nette\Mail\Message; /** * \Mail */ class Mail extends Message { public $config; // [String] e-mail protected $from; // [Array] e-mail list protected $to; protected $title; protected $body; function __construct($to) { $this->config = require BASE_PATH.'/config/mail.php'; $this->setFrom($this->config['username']); if ( is_array($to) ) { foreach ($to as $email) { $this->addTo($email); } } else { $this->addTo($to); } } public function from($from=null) { if ( !$from ) { throw new InvalidArgumentException("邮件发送地址不能为空!"); } $this->setFrom($from); return $this; } public static function to($to=null) { if ( !$to ) { throw new InvalidArgumentException("邮件接收地址不能为空!"); } return new Mail($to); } public function title($title=null) { if ( !$title ) { throw new InvalidArgumentException("邮件标题不能为空!"); } $this->setSubject($title); return $this; } public function content($content=null) { if ( !$content ) { throw new InvalidArgumentException("邮件内容不能为空!"); } $this->setHTMLBody($content); return $this; } }
Mail 类和 View 类工做的方式基本一致:composer
$this->mail = Mail::to(['ooxx@gmail.com', 'ooxx@qq.com']) ->from('MotherFucker <ooxx@163.com>') ->title('Fuck Me!') ->content('<h1>Hello~~</h1>');
上面这段代码位于 HomeController 中, View::make()
那行代码的下面。框架
新建 MFFC/config/mail.php
,请自行替换邮件地址和密码:异步
<?php return [ 'host' => 'smtp.163.com', 'username' => 'ooxx@163.com', 'password' => 'password', 'secure' => '' ];
Mail 和 View 同样也在 BaseController 的析构函数 __destruct() 函数中处理,如今这个 function 长这样:
public function __destruct() { $view = $this->view; if ( $view instanceof View ) { extract($view->data); require $view->view; } $mail = $this->mail; if ( $mail instanceof Mail ) { $mailer = new Nette\Mail\SmtpMailer($mail->config); $mailer->send($mail); } }
OK,准备的差很少了,运行 composer dump-autoload
把 Mail 类加入自动加载,刷新页面!
若是你看到以上页面,恭喜你!邮件发送成功了!
赶快去检查一下收件箱有木有邮件!:-D 此次页面加载可能会稍慢,由于邮件是同步发送的。异步的队列系统咱们会在之后讲到。
邮件发送的总体流程想必你们已经轻车熟路了,如今主要叙述一下 Mail 类的设计过程:
目标地址
,即邮件要发送到的 E-mail 地址,因此咱们设计 Mail::to('oo@xx.me') 做为发送的 触发 API
。SMTP
方式发送邮件,文档在 这里。配置文件放置在 MFFC/config/mail.php
中,依旧返回一个数组。Nette\Mail\Message
类。Mail::to()
的时候建立一个 Mail 类的实例(对象)并返回,这时候其实 BaseController
中的析构函数中的代码已经会被触发并处理这个对象了。默认的发送人是从配置文件中读取的 username
。Mail::to()
支持 字符串 或者数组做为参数,能够一次发送一封或多封邮件。from()
、title()
和 content()
方法用于丰富邮件内容。content()
方法能够直接传递 HTML 代码。from()
配置不必定都可以成功,部分邮件服务商不支持修改发送人地址。$mail
成员变量,而后被析构函数处理,邮件被发送,成功后页面代码被发送回客户端,流程结束。