php下使用SMTP發(fā)郵件的代碼
更新時(shí)間:2008年01月10日 20:37:22 作者:
php下使用SMTP發(fā)郵件的代碼
最近一個(gè)項(xiàng)目需要用到SMTP發(fā)送郵件,之前的庫(kù)類(lèi)不存在了,又不喜歡安裝pear或者使用pear的net/smtp類(lèi),感覺(jué)太復(fù)雜了。就直接從discuz中抽取出核心稍微修改了下。
從協(xié)議分析網(wǎng)上,查找到SMTP協(xié)議的命令和應(yīng)答,SMTP協(xié)議在發(fā)送SMTP和接收SMTP之間的會(huì)話是靠發(fā)送SMTP的SMTP命令和接收SMTP反饋的應(yīng)答來(lái)完成的。常用的命令如下:
HELLO<domain><CRLF>識(shí)別發(fā)送方到接收SMTP的一個(gè)HELLO命令
MAIL FROM:<reverse-path><CRLF><reverse-path>為發(fā)送者地址。此命令告訴接收方一個(gè)新郵件發(fā)送的開(kāi)始,并對(duì)所有的狀態(tài)和緩沖區(qū)進(jìn)行初始化。此命令開(kāi)始一個(gè)郵件傳輸處理,最終完成將郵件數(shù)據(jù)傳送到一個(gè)或多個(gè)郵箱中。
RCPT TO:<forward-path><CRLF><forward-path>標(biāo)識(shí)各個(gè)郵件接收者的地址
DATA<CRLF>
接收SMTP將把其后的行為看作郵件數(shù)據(jù)去處理,以<CRLF>.<CRLF>標(biāo)識(shí)數(shù)據(jù)的結(jié)尾。
REST<CRLF>退出/復(fù)位當(dāng)前的郵件傳輸
NOOP<CRLF>要求接收SMTP僅做OK應(yīng)答。(用于測(cè)試)
QUIT<CRLF>要求接收SMTP返回一個(gè)OK應(yīng)答并關(guān)閉傳輸。
VRFY<string><CRLF>驗(yàn)證指定的郵箱是否存在,由于安全因素,服務(wù)器多禁止此命令。
EXPN<string><CRLF>驗(yàn)證給定的郵箱列表是否存在,擴(kuò)充郵箱列表,也常禁止使用。
HELP<CRLF>查詢(xún)服務(wù)器支持什么命令
注:<CRLF>為回車(chē)、換行,ASCII碼分別為13、10(十進(jìn)制)。
另外,可以在command下,使用telnet來(lái)進(jìn)行簡(jiǎn)單的手工使用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.
在此基礎(chǔ)上就可以寫(xiě)出一個(gè)簡(jiǎn)單的SMTP類(lèi)了。
<?
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;
}
}
?>
簡(jiǎn)單的調(diào)用例子:
<?
$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'=>'測(cè)試標(biāo)題','content'=>'郵件內(nèi)容<a );
if(!$stmp->send($mail)){
echo $stmp->get_error();
}else{
echo 'mail succ!';
}
?>
如果發(fā)送成功,你就可以去郵箱查看郵件了。^_^
從協(xié)議分析網(wǎng)上,查找到SMTP協(xié)議的命令和應(yīng)答,SMTP協(xié)議在發(fā)送SMTP和接收SMTP之間的會(huì)話是靠發(fā)送SMTP的SMTP命令和接收SMTP反饋的應(yīng)答來(lái)完成的。常用的命令如下:
HELLO<domain><CRLF>識(shí)別發(fā)送方到接收SMTP的一個(gè)HELLO命令
MAIL FROM:<reverse-path><CRLF><reverse-path>為發(fā)送者地址。此命令告訴接收方一個(gè)新郵件發(fā)送的開(kāi)始,并對(duì)所有的狀態(tài)和緩沖區(qū)進(jìn)行初始化。此命令開(kāi)始一個(gè)郵件傳輸處理,最終完成將郵件數(shù)據(jù)傳送到一個(gè)或多個(gè)郵箱中。
RCPT TO:<forward-path><CRLF><forward-path>標(biāo)識(shí)各個(gè)郵件接收者的地址
DATA<CRLF>
接收SMTP將把其后的行為看作郵件數(shù)據(jù)去處理,以<CRLF>.<CRLF>標(biāo)識(shí)數(shù)據(jù)的結(jié)尾。
REST<CRLF>退出/復(fù)位當(dāng)前的郵件傳輸
NOOP<CRLF>要求接收SMTP僅做OK應(yīng)答。(用于測(cè)試)
QUIT<CRLF>要求接收SMTP返回一個(gè)OK應(yīng)答并關(guān)閉傳輸。
VRFY<string><CRLF>驗(yàn)證指定的郵箱是否存在,由于安全因素,服務(wù)器多禁止此命令。
EXPN<string><CRLF>驗(yàn)證給定的郵箱列表是否存在,擴(kuò)充郵箱列表,也常禁止使用。
HELP<CRLF>查詢(xún)服務(wù)器支持什么命令
注:<CRLF>為回車(chē)、換行,ASCII碼分別為13、10(十進(jìn)制)。
另外,可以在command下,使用telnet來(lái)進(jìn)行簡(jiǎn)單的手工使用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.
在此基礎(chǔ)上就可以寫(xiě)出一個(gè)簡(jiǎn)單的SMTP類(lèi)了。
<?
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;
}
}
?>
簡(jiǎn)單的調(diào)用例子:
<?
$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'=>'測(cè)試標(biāo)題','content'=>'郵件內(nèi)容<a );
if(!$stmp->send($mail)){
echo $stmp->get_error();
}else{
echo 'mail succ!';
}
?>
如果發(fā)送成功,你就可以去郵箱查看郵件了。^_^
您可能感興趣的文章:
- PHPMailer使用教程(PHPMailer發(fā)送郵件實(shí)例分析)
- php郵件發(fā)送的兩種方式
- 功能齊全的PHP發(fā)送郵件類(lèi)代碼附詳細(xì)說(shuō)明
- php中通過(guò)smtp發(fā)郵件的類(lèi),測(cè)試通過(guò)
- php郵件發(fā)送,php發(fā)送郵件的類(lèi)
- PHPMailer郵件類(lèi)利用smtp.163.com發(fā)送郵件方法
- phpmailer在服務(wù)器上不能正常發(fā)送郵件的解決辦法
- phpmailer簡(jiǎn)單發(fā)送郵件的方法(附phpmailer源碼下載)
- php中mail函數(shù)發(fā)送郵件失敗的解決方法
- PHP receiveMail實(shí)現(xiàn)收郵件功能
相關(guān)文章
對(duì)PHP依賴(lài)注入的理解實(shí)例分析
這篇文章主要介紹了對(duì)PHP依賴(lài)注入的理解,結(jié)合實(shí)例形式詳細(xì)分析了PHP依賴(lài)注入的相關(guān)概念與原理,需要的朋友可以參考下2016-10-10
給初學(xué)者的30條PHP最佳實(shí)踐(荒野無(wú)燈)
給初學(xué)者的30條PHP最佳實(shí)踐,需要的朋友可以參考下。2011-08-08
關(guān)于PHP模板Smarty的初級(jí)使用方法以及心得分享
本篇文章是對(duì)PHP模板Smarty的初級(jí)使用方法以及心得進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
php 移除數(shù)組重復(fù)元素的一點(diǎn)說(shuō)明
PHP中移除數(shù)組重復(fù)元素用的函數(shù)是array_unique2008-11-11
PHP取整數(shù)函數(shù)常用的四種方法小結(jié)
PHP取整數(shù)函數(shù)常用的四種方法,下面收集了四個(gè)函數(shù);經(jīng)常用到取整的函數(shù),今天小小的總結(jié)一下!其實(shí)很簡(jiǎn)單,就是幾個(gè)函數(shù)而已~~主要是:ceil,floor,round,intval2012-07-07

