利用 Composer 完善自己的 PHP 框架(二)——发送邮件
本教程示例代码见 https://github.com/johnlui/My-First-Framework-based-on-Composer
回顾
上一篇文章中,我们手工建造了一个简易的视图加载器,顺便引入了错误处理包,让我们的 MFFC 框架在 M、V、C 三个方面都达到了“好用”的水平。View 是一个可插拔组件,在本篇文章中我们要创建另一个可插拔组件——邮件发送模块。
正文
我们采用 'nette/mail' 包作为我们的邮件发送基础模块,在它的基础上封装一个 'Mail' 类,暴露出简洁的 API 给控制器使用,下面我们正式开始。
引入 'nette/mail' 包,修改 'composer.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 类工作的方式基本一致:
$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' 中,依旧返回一个数组。
- Mail 类继承了 'Nette\Mail\Message' 类。'Mail::to()' 的时候创建一个 Mail 类的实例(对象)并返回,这时候其实 'BaseController' 中的析构函数中的代码已经会被触发并处理这个对象了。默认的发送人是从配置文件中读取的 'username'。
- 'Mail::to()' 支持 字符串 或者数组作为参数,可以一次发送一封或多封邮件。
- 'from()'、'title()' 和 'content()' 方法用于丰富邮件内容。'content()' 方法可以直接传递 HTML 代码。
- 'from()' 配置不一定都能够成功,部分邮件服务商不支持修改发送人地址。
- 这个变量全部组装完成后,被赋值给控制器的 '$mail' 成员变量,然后被析构函数处理,邮件被发送,成功后页面代码被发送回客户端,流程结束。
https://lvwenhan.com/php/412.html
利用 Composer 完善自己的 PHP 框架(二)——发送邮件的更多相关文章
- 利用 Composer 完善自己的 PHP 框架(一)——视图装载
本教程示例代码见 https://github.com/johnlui/My-First-Framework-based-on-Composer 回顾 经过了上一个 系列教程 <利用 Comp ...
- 【完结】利用 Composer 完善自己的 PHP 框架(三)——Redis 缓存
本教程示例代码见 https://github.com/johnlui/My-First-Framework-based-on-Composer 回顾 上两篇文章中我们完成了 View 视图加载类和 ...
- 利用 Composer 一步一步构建自己的 PHP 框架(一)——基础准备
『Composer 一统天下的时代已经到来!』——白岩松 “一个时代结束了,另一个时代开始了.” Framework Interoperability Group(框架可互用性小组),简称 FIG,成 ...
- php 利用composer引用第三方类库构建项目
经常看到各种开源库推荐使用 composer 安装代码,却总是看不懂怎么用composer, 这几天静下心来学习了composer的使用,发现这可真是一个好东西,先贴上一个讲的很棒的视频教程: PHP ...
- 【实践】如何利用tensorflow的object_detection api开源框架训练基于自己数据集的模型(Windows10系统)
如何利用tensorflow的object_detection api开源框架训练基于自己数据集的模型(Windows10系统) 一.环境配置 1. Python3.7.x(注:我用的是3.7.3.安 ...
- Jersey框架二:Jersey对JSON的支持
Jersey系列文章: Jersey框架一:Jersey RESTful WebService框架简介 Jersey框架二:Jersey对JSON的支持 Jersey框架三:Jersey对HTTPS的 ...
- 利用jQuery扩展接口为jQuery框架定义了两个自定义函数,然后调用这两个函数
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 第三百二十一节,Django框架,发送邮件
第三百二十一节,Django框架,发送邮件 全局配置settings.py EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' ...
- Yii框架(二)Model处理数据
熟悉php的autoload机制,自己实现一个autoload函数 一.复习框架: basic/ 应用根目录 composer.json Composer 配置文件, 描述包信息 config/ 包含 ...
随机推荐
- Linux性能监控之Memory篇
首先说说虚拟内存和物理内存: 虚拟内存就是采用硬盘来对物理内存进行扩展,将暂时不用的内存页写到硬盘上而腾出更多的物理内存让有需要的进程来用.当这些内存页需要用的时候在从硬盘读回内存.这一切对于用户来说 ...
- Redis3.0 Install
Installation Download, extract and compile Redis with: $ wget http://download.redis.io/releases/redi ...
- AHOI2013 Round2 Day2 简要题解
第一题: 第一问可以用划分树或主席树在O(nlog2n)内做出来. 第二问可以用树状数组套主席树在O(nlog2n)内做出来. 我的代码太挫了,空间刚刚卡过...(在bzoj上) 第二题: 分治,将询 ...
- 小C的填数游戏
题意: 给出一张n个点的无向图 i连向i-1和i-2 边权为wij 有两个点权ai和bi ai为0或1 在给m个操作 1.将ai异或1 2.将区间x到y的点都填上一个数ci 使得Σ(bi*(ai^ci ...
- erlang局域网内节点通信——艰难四步曲 (转)
http://blog.chinaunix.net/uid-22566367-id-382011.html 在Programming Erlang这本书中,在写到第十章中,主要实现的是不同节点之间的通 ...
- Codeforces Round #372 (Div. 1) B. Complete The Graph (枚举+最短路)
题目就是给你一个图,图中部分边没有赋权值,要求你把无权的边赋值,使得s->t的最短路为l. 卡了几周的题了,最后还是经群主大大指点……做出来的…… 思路就是跑最短路,然后改权值为最短路和L的差值 ...
- 采用现代Objective-C
多年来,Objective-C语言已经有了革命性的发展.虽然核心理念和实践保持不变,但语言中的部分内容经历了重大的变化和改进.现代化的Objective-C在类型安全.内存管理.性能.和其他方面都得到 ...
- nyoj 120 校园网络(求添加多少条边使整个图强连通)
校园网络 时间限制:3000 ms | 内存限制:65535 KB 难度:5 描述 南阳理工学院共有M个系,分别编号1~M,其中各个系之间达成有一定的协议,如果某系有新软件可用时,该系将允许一 ...
- C#中ArrayList和string,string[]数组的转换
转载原地址: http://www.cnblogs.com/nextsoft/articles/2218689.html 1.ArrarList 转换为 string[] : ArrayList li ...
- 2015年必火的五个Html5移动开发工具推荐
NO.1 DCloudHBuilder:基于HTML5开发工具 中文官网:http://www.dcloud.io/ DCloudHBuilder:基于HTML5开发工具是当前最快的HTML开发工 ...