php 利用个人邮箱,利用 Composer 完善自己的 PHP 框架(二)——发送邮件
利用 Composer 完善自己的 PHP 框架(二)——發送郵件
2014-10-18 / 閱讀數:23506 / 分類: PHP
回顧
上一篇文章中,我們手工建造了一個簡易的視圖加載器,順便引入了錯誤處理包,讓我們的 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;
/**
*/
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 ')
->title('Fuck Me!')
->content('
Hello~~
');上面這段代碼位于 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' 成員變量,然后被析構函數處理,郵件被發送,成功后頁面代碼被發送回客戶端,流程結束。
WRITTEN BY
程序員,Swift Contributor,正在寫《iOS 可視化編程與 Auto Layout》。
評論:
lhh
2018-03-02 14:10
phpstorm 點進去能找到mail類,但是報錯是Class 'Services\Mail' not found
daode
2020-08-25 18:31
@lhh:composer dump-autoload 試試
小樣
2018-01-31 15:37
按照配置配置完成mail服務之后,報錯
SMTP server did not accept . with error: 554 DT:SPM 163 smtp2,DNGowACnMfatcXFaOgQVAA--.297S2 1517384109,please see http://mail.163.com/help/help_spam_16.htm?ip=61.149.143.14&hostid=smtp2&time=1517384109
請問博主,這是啥情況呢?是配置項沒有配對還是程序驗證上哪里出問題了呢
jason
2017-07-10 16:43
我想請教大佬@JohnLui,到目前為止,View或者Mail這類功能再析構中觸發是基于性能考慮,或者是什么考慮?
2017-07-10 16:49
@jason:我把 TinyView 放到析構中觸發是為了不侵入主流程。。。
至于 Mail,這東西比較耗時,實際場景下一般使用隊列系統,異步發送。
haha
2017-06-06 19:25
config/mail.php 由163換車搜狐的郵箱就可以了,163的郵箱安全驗證比較嚴格導致
return [
'host'???? => 'smtp.sohu.com',
'username' => 'xxxxx@sohu.com',
'password' => 'xxxxx',
'secure'?? => ''
];
kun
2017-04-05 19:44
我的也沒有報錯,效果也和博主的一樣,可為什么沒有收到呢 ,應該還是發送不成功。
crlt_
2018-01-17 10:34
@kun:可以看看你的垃圾箱
風無心
2016-08-18 18:22
markdown寫出來的文檔,直接讓人有種跪舔的沖動
woodstig3
2015-08-21 21:48
按照教主的示例做下來,總是返回:“No connection could be made because the target machine actively refused it.”這好像是SMTP服務器的設置問題,但是查看了163的郵箱設置,確實打開了SMTP服務了,為什么無法連接上呢?
woodstig3
2015-08-23 15:25
@woodstig3:問題沒有找到,但是從教主的github主頁上把Mail.php下下來重新跑就沒這個問題了。但是郵件似乎還沒有發出去。再查!
發表評論:
昵稱
郵件地址 (選填)
個人主頁 (選填)
總結
以上是生活随笔為你收集整理的php 利用个人邮箱,利用 Composer 完善自己的 PHP 框架(二)——发送邮件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【LeetCode笔记】438. 找到字
- 下一篇: python类的私有属性_Python类