php下使用SMTP發郵件的代碼

來源:互聯網
上載者:User

最近一個項目需要用到SMTP發送郵件,之前的庫類不存在了,又不喜歡安裝pear或者使用pear的net/smtp類,感覺太複雜了。就直接從discuz中抽取出核心稍微修改了下。
從協議分析網上,尋找到SMTP協議的命令和應答,SMTP協議在發送SMTP和接收SMTP之間的會話是靠發送SMTP的SMTP命令和接收SMTP反饋的應答來完成的。常用的命令如下:
HELLO<domain><CRLF>識別發送方到接收SMTP的一個HELLO命令
MAIL FROM:<reverse-path><CRLF><reverse-path>為寄件者地址。此命令告訴接收方一個新郵件發送的開始,並對所有的狀態和緩衝區進行初始化。此命令開始一個郵件傳輸處理,最終完成將郵件資料傳送到一個或多個郵箱中。
RCPT TO:<forward-path><CRLF><forward-path>標識各個郵件接收者的地址
DATA<CRLF>
接收SMTP將把其後的行為看作郵件資料去處理,以<CRLF>.<CRLF>標識資料的結尾。
REST<CRLF>退出/複位當前的郵件傳輸
NOOP<CRLF>要求接收SMTP僅做OK應答。(用於測試)
QUIT<CRLF>要求接收SMTP返回一個OK應答並關閉傳輸。
VRFY<string><CRLF>驗證指定的郵箱是否存在,由於安全因素,伺服器多禁止此命令。
EXPN<string><CRLF>驗證給定的郵箱列表是否存在,擴充郵箱列表,也常禁止使用。
HELP<CRLF>查詢服務器支援什麼命令

註:<CRLF>為斷行符號、換行,ASCII碼分別為13、10(十進位)。

另外,可以在command下,使用telnet來進行簡單的手工使用SMTP。
比如:

telnet smtp.263.net 25
Trying 211.150.96.25...
Connected to smtp.263.net.
Escape character is '^]'.
220 Welcome to coremail System(With Anti-Spam) 2.1 for 263(040326)
HELO weiqiong@cctk.net
250 smtp.263.net
mail from:weiqiong@cctk.net
250 Ok
rcpt to:g2_t1@263.net
250 Ok
data
354 End data with <CR><LF>.<CR><LF>
haha
.
250 Ok: queued as B9E452FF3E
quit
221 Bye
Connection closed by foreign host.

在此基礎上就可以寫出一個簡單的SMTP類了。

<?
class stmp{

private $mailcfg=array();
private $error_msg='';

function __construct($mailcfg){

$this->mailcfg=$mailcfg;

}

public function send($mail){
$mailcfg=$this->mailcfg;
if(!$fp = fsockopen($mailcfg['server'], $mailcfg['port'], $errno, $errstr, 30)) {
return $this->error("($mailcfg[server]:$mailcfg[port]) CONNECT - Unable to connect to the SMTP server, please check your \"mail_config.php\".");
}
stream_set_blocking($fp, true);
$lastmessage = fgets($fp, 512);
if(substr($lastmessage, 0, 3) != '220') {
return $this->error("$mailcfg[server]:$mailcfg[port] CONNECT - $lastmessage");
}
fputs($fp, ($mailcfg['auth'] ? 'EHLO' : 'HELO')." ".$mailcfg['auth_username']."\r\n");
$lastmessage = fgets($fp, 512);
if(substr($lastmessage, 0, 3) != 220 && substr($lastmessage, 0, 3) != 250) {
return $this->error("($mailcfg[server]:$mailcfg[port]) HELO/EHLO - $lastmessage");
}
while(1) {
if(substr($lastmessage, 3, 1) != '-' || empty($lastmessage)) {
break;
}
$lastmessage = fgets($fp, 512);
}
if($mailcfg['auth']) {
fputs($fp, "AUTH LOGIN\r\n");
$lastmessage = fgets($fp, 512);
if(substr($lastmessage, 0, 3) != 334) {
return $this->error("($mailcfg[server]:$mailcfg[port]) AUTH LOGIN - $lastmessage");
}
fputs($fp, base64_encode($mailcfg['auth_username'])."\r\n");
$lastmessage = fgets($fp, 512);
if(substr($lastmessage, 0, 3) != 334) {
return $this->error("($mailcfg[server]:$mailcfg[port]) USERNAME - $lastmessage");
}

fputs($fp, base64_encode($mailcfg['auth_password'])."\r\n");
$lastmessage = fgets($fp, 512);
if(substr($lastmessage, 0, 3) != 235) {
return $this->error("($mailcfg[server]:$mailcfg[port]) PASSWORD - $lastmessage");
}

$email_from = $mailcfg['from'];
}
fputs($fp, "MAIL FROM: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $email_from).">\r\n");
$lastmessage = fgets($fp, 512);
if(substr($lastmessage, 0, 3) != 250) {
fputs($fp, "MAIL FROM: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $email_from).">\r\n");
$lastmessage = fgets($fp, 512);
if(substr($lastmessage, 0, 3) != 250) {
return $this->error("($mailcfg[server]:$mailcfg[port]) MAIL FROM - $lastmessage");
}
}

$email_to=$mail['to'];
foreach(explode(',', $email_to) as $touser) {
$touser = trim($touser);
if($touser) {
fputs($fp, "RCPT TO: <$touser>\r\n");
$lastmessage = fgets($fp, 512);
if(substr($lastmessage, 0, 3) != 250) {
fputs($fp, "RCPT TO: <$touser>\r\n");
$lastmessage = fgets($fp, 512);
return $this->error("($mailcfg[server]:$mailcfg[port]) RCPT TO - $lastmessage");
}
}
}
fputs($fp, "DATA\r\n");
$lastmessage = fgets($fp, 512);
if(substr($lastmessage, 0, 3) != 354) {
return $this->error("($mailcfg[server]:$mailcfg[port]) DATA - $lastmessage");
}
$str="To: $email_to\r\nFrom: $email_from\r\nSubject: ".$mail['subject']."\r\n\r\n".$mail['content']."\r\n.\r\n";
fputs($fp, $str);
fputs($fp, "QUIT\r\n");
return true;
}

public function get_error(){
return $this->error_msg;
}

private function error($msg){
$this->error_msg.=$msg;
return false;
}

}
?>

簡單的調用例子:

<?
$mailcfg['server'] = 'smtp.163.com';

$mailcfg['port'] = '25';

$mailcfg['auth'] = 1;
$mailcfg['from'] = 'test <test@163.com>';

$mailcfg['auth_username'] = 'test';

$mailcfg['auth_password'] = 'password';
$stmp=new stmp($mailcfg);
$mail=array('to'=>'test@gmail.com','subject'=>'測試標題','content'=>'郵件內容<a href="http://www.phpobject.net">PHP物件導向</a>');
if(!$stmp->send($mail)){
echo $stmp->get_error();
}else{
echo 'mail succ!';
}
?>

如果發送成功,你就可以去郵箱查看郵件了。^_^

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.