smtp邮件发送一例


Posted in PHP onOctober 09, 2006

test_smtp.php

<?
require("smtp.php");

$smtp=new smtp_class;

$smtp->host_name="mail.xiaocui.com";
$smtp->localhost="localhost";
$from="webmaster@xiaocui.com";
$to="root@xiaocui.com";
if($smtp->SendMessage(
  $from,
  array(
   $to
  ),
  array(
   "From: $from",
   "To: $to",
   "Subject: Testing Manuel Lemos' SMTP class"
  ),
  "Hello $to,\n\nIt is just to let you know that your SMTP class is working just fine.\n\nBye.\n"))
  echo "Message sent to $to OK.\n";
else
  echo "Cound not send the message to $to.\nError: ".$smtp->error."\n"
?>

smtp.php

<?

class smtp_class
{
var $host_name="";
var $host_port=25;
var $localhost="";
var $timeout=0;
var $error="";
var $debug=1;
var $esmtp=1;
var $esmtp_host="";
var $esmtp_extensions=array();
var $maximum_piped_recipients=100;

/* private variables - DO NOT ACCESS */

var $state="Disconnected";
var $connection=0;
var $pending_recipients=0;

/* Private methods - DO NOT CALL */

Function OutputDebug($message)
{
  echo $message,"<br>\n";
}

Function GetLine()
{
  for($line="";;)
  {
   if(feof($this->connection))
   {
    $this->error="reached the end of stream while reading from socket";
    return(0);
   }
   if(($data=fgets($this->connection,100))==false)
   {
    $this->error="it was not possible to read line from socket";
    return(0);
   }
   $line.=$data;
   $length=strlen($line);
   if($length>=2
   && substr($line,$length-2,2)=="\r\n")
   {
    $line=substr($line,0,$length-2);
    if($this->debug)
     $this->OutputDebug("< $line");
    return($line);
   }
  }
}

Function PutLine($line)
{
  if($this->debug)
   $this->OutputDebug("> $line");
  if(!fputs($this->connection,"$line\r\n"))
  {
   $this->error="it was not possible to write line to socket";
   return(0);
  }
  return(1);
}

Function PutData($data)
{
  if(strlen($data))
  {
   if($this->debug)
    $this->OutputDebug("> $data");
   if(!fputs($this->connection,$data))
   {
    $this->error="it was not possible to write data to socket";
    return(0);
   }
  }
  return(1);
}

Function VerifyResultLines($code,$responses="")
{
  if(GetType($responses)!="array")
   $responses=array();
  Unset($match_code);

  while(($line=$this->GetLine($this->connection)))
  {
   if(IsSet($match_code))
   {
    if(strcmp(strtok($line," -"),$match_code))
    {
     $this->error=$line;
     return(0);
    }
   }
   else
   {
    $match_code=strtok($line," -");
    if(GetType($code)=="array")
    {
     for($codes=0;$codes<count($code) && strcmp($match_code,$code[$codes]);$codes++);
     if($codes>=count($code))
     {
      $this->error=$line;
      return(0);
     }
    }
    else
    {
     if(strcmp($match_code,$code))
     {
      $this->error=$line;
      return(0);
     }
    }
   }
   $responses[]=strtok("");
   if(!strcmp($match_code,strtok($line," ")))
    return(1);
  }
  return(-1);
}

Function FlushRecipients()
{
  if($this->pending_sender)
  {
   if($this->VerifyResultLines("250")<=0)
    return(0);
   $this->pending_sender=0;
  }
  for(;$this->pending_recipients;$this->pending_recipients--)
  {
   if($this->VerifyResultLines(array("250","251"))<=0)
    return(0);
  }
  return(1);
}

/* Public methods */

Function Connect()
{
  $this->error=$error="";
   $this->esmtp_host="";
   $this->esmtp_extensions=array();
  if(!($this->connection=($this->timeout ? fsockopen($this->host_name,$this->host_port,&$errno,&$error,$this->timeout) : fsockopen($this->host_name,$this->host_port))))
  {
   switch($error)
   {
    case -3:
     $this->error="-3 socket could not be created";
     return(0);
    case -4:
     $this->error="-4 dns lookup on hostname \"".$host_name."\" failed";
     return(0);
    case -5:
     $this->error="-5 connection refused or timed out";
     return(0);
    case -6:
     $this->error="-6 fdopen() call failed";
     return(0);
    case -7:
     $this->error="-7 setvbuf() call failed";
     return(0);
    default:
     $this->error=$error." could not connect to the host \"".$this->host_name."\"";
     return(0);
   }
  }
  else
  {
   if(!strcmp($localhost=$this->localhost,"")
   && !strcmp($localhost=getenv("SERVER_NAME"),"")
   && !strcmp($localhost=getenv("HOST"),""))
     $localhost="localhost";
    $success=0;
    if($this->VerifyResultLines("220")>0)
    {
     if($this->esmtp)
     {
      $responses=array();
      if($this->PutLine("EHLO $localhost")
      && $this->VerifyResultLines("250",&$responses)>0)
      {
       $this->esmtp_host=strtok($responses[0]," ");
       for($response=1;$response<count($responses);$response++)
       {
        $extension=strtoupper(strtok($responses[$response]," "));
        $this->esmtp_extensions[$extension]=strtok("");
       }
       $success=1;
      }
     }
     if(!$success
     && $this->PutLine("HELO $localhost")
     && $this->VerifyResultLines("250")>0)
      $success=1;
   }
   if($success)
   {
    $this->state="Connected";
    return(1);
   }
   else
   {
    fclose($this->connection);
    $this->connection=0;
    $this->state="Disconnected";
    return(0);
   }
  }
}

Function MailFrom($sender)
{
  if(strcmp($this->state,"Connected"))
  {
   $this->error="connection is not in the initial state";
   return(0);
  }
  $this->error="";
  if(!$this->PutLine("MAIL FROM: <".$sender.">"))
   return(0);
  if(!IsSet($this->esmtp_extensions["PIPELINING"])
  && $this->VerifyResultLines("250")<=0)
   return(0);
  $this->state="SenderSet";
  if(IsSet($this->esmtp_extensions["PIPELINING"]))
   $this->pending_sender=1;
  $this->pending_recipients=0;
  return(1);
}

Function SetRecipient($recipient)
{
  switch($this->state)
  {
   case "SenderSet":
   case "RecipientSet":
    break;
   default:
    $this->error="connection is not in the recipient setting state";
    return(0);
  }
  $this->error="";
  if(!$this->PutLine("RCPT TO:<".$recipient.">"))
   return(0);
  if(IsSet($this->esmtp_extensions["PIPELINING"]))
  {
   $this->pending_recipients++;
   if($this->pending_recipients>=$this->maximum_piped_recipients)
   {
    if(!$this->FlushRecipients())
     return(0);
   }
  }
  else
  {
   if($this->VerifyResultLines(array("250","251"))<=0)
    return(0);
  }
  $this->state="RecipientSet";
  return(1);
}

Function StartData()
{
  if(strcmp($this->state,"RecipientSet"))
  {
   $this->error="connection is not in the start sending data state";
   return(0);
  }
  $this->error="";
  if(!$this->PutLine("DATA"))
   return(0);
  if($this->pending_recipients)
  {
   if(!$this->FlushRecipients())
    return(0);
  }
  if($this->VerifyResultLines("354")<=0)
   return(0);
  $this->state="SendingData";
  return(1);
}

Function PrepareData($data,&$output)
{
  $length=strlen(&$data);
  for($output="",$position=0;$position<$length;)
  {
   $next_position=$length;
   for($current=$position;$current<$length;$current++)
   {
    switch($data[$current])
    {
     case "\n":
      $next_position=$current+1;
      break 2;
     case "\r":
      $next_position=$current+1;
      if($data[$next_position]=="\n")
       $next_position++;
      break 2;
    }
   }
   if($data[$position]==".")
    $output.=".";
   $output.=substr(&$data,$position,$current-$position)."\r\n";
   $position=$next_position;
  }
}

Function SendData($data)
{
  if(strcmp($this->state,"SendingData"))
  {
   $this->error="connection is not in the sending data state";
   return(0);
  }
  $this->error="";
  return($this->PutData(&$data));
}

Function EndSendingData()
{
  if(strcmp($this->state,"SendingData"))
  {
   $this->error="connection is not in the sending data state";
   return(0);
  }
  $this->error="";
  if(!$this->PutLine("\r\n.")
  || $this->VerifyResultLines("250")<=0)
   return(0);
  $this->state="Connected";
  return(1);
}

Function ResetConnection()
{
  switch($this->state)
  {
   case "Connected":
    return(1);
   case "SendingData":
    $this->error="can not reset the connection while sending data";
    return(0);
   case "Disconnected":
    $this->error="can not reset the connection before it is established";
    return(0);
  }
  $this->error="";
  if(!$this->PutLine("RSET")
  || $this->VerifyResultLines("250")<=0)
   return(0);
  $this->state="Connected";
  return(1);
}

Function Disconnect($quit=1)
{
  if(!strcmp($this->state,"Disconnected"))
  {
   $this->error="it was not previously established a SMTP connection";
   return(0);
  }
  $this->error="";
  if(!strcmp($this->state,"Connected")
  && $quit
  && (!$this->PutLine("QUIT")
  || $this->VerifyResultLines("221")<=0))
   return(0);
  fclose($this->connection);
  $this->connection=0;
  $this->state="Disconnected";
  return(1);
}

Function SendMessage($sender,$recipients,$headers,$body)
{
  if(($success=$this->Connect()))
  {
   if(($success=$this->MailFrom($sender)))
   {
    for($recipient=0;$recipient<count($recipients);$recipient++)
    {
     if(!($success=$this->SetRecipient($recipients[$recipient])))
      break;
    }
    if($success
    && ($success=$this->StartData()))
    {
     for($header_data="",$header=0;$header<count($headers);$header++)
      $header_data.=$headers[$header]."\r\n";
     if(($success=$this->SendData($header_data."\r\n")))
     {
      $this->PrepareData($body,&$body_data);
      $success=$this->SendData($body_data);
     }
     if($success)
      $success=$this->EndSendingData();
    }
   }
   $disconnect_success=$this->Disconnect($success);
   if($success)
    $success=$disconnect_success;
  }
  return($success);
}

};

?>

PHP 相关文章推荐
PHP中如何判断AJAX提交的数据
Feb 05 PHP
php创建和删除目录函数介绍和递归删除目录函数分享
Nov 18 PHP
php获取QQ头像并显示的方法
Dec 23 PHP
PHP.ini安全配置检测工具pcc简单介绍
Jul 02 PHP
php实现表单多按钮提交action的处理方法
Oct 24 PHP
ThinkPHP路由机制简介
Mar 23 PHP
php 运算符与表达式详细介绍
Nov 30 PHP
PHP使用finfo_file()函数检测上传图片类型的实现方法
Apr 18 PHP
Laravel框架实现修改登录和注册接口数据返回格式的方法
Aug 17 PHP
php微信公众号开发之关键词回复
Oct 20 PHP
PHP配合fiddler抓包抓取微信指数小程序数据的实现方法分析
Jan 02 PHP
PHP实现创建一个RPC服务操作示例
Feb 23 PHP
图片存储与浏览一例(Linux+Apache+PHP+MySQL)
Oct 09 #PHP
PHP+javascript液晶时钟
Oct 09 #PHP
一个分页的论坛
Oct 09 #PHP
一个简易需要注册的留言版程序
Oct 09 #PHP
使用数据库保存session的方法
Oct 09 #PHP
COM in PHP (winows only)
Oct 09 #PHP
Banner程序
Oct 09 #PHP
You might like
短波的认识
2021/03/01 无线电
php动态生成JavaScript代码
2009/03/09 PHP
php比较多维数组中值的大小排序实现代码
2012/09/08 PHP
PHP设计模式之代理模式的深入解析
2013/06/13 PHP
php生成随机颜色方法汇总
2014/12/03 PHP
Aster vs Newbee BO5 第二场2.19
2021/03/10 DOTA
ExtJS 2.0实用简明教程 之获得ExtJS
2009/04/29 Javascript
js当一个变量为函数时 应该注意的一点细节小结
2011/12/29 Javascript
jquery创建一个新的节点对象(自定义结构/内容)的好方法
2013/01/21 Javascript
打造个性化的功能强大的Jquery虚拟键盘(VirtualKeyboard)
2014/10/11 Javascript
一个JavaScript操作元素定位元素的实例
2014/10/29 Javascript
JavaScript 性能优化小结
2015/10/12 Javascript
js实现卡片式项目管理界面UI设计效果
2015/12/08 Javascript
Bootstrap3.0学习教程之JS折叠插件
2016/05/27 Javascript
jQuery遍历节点树方法分析
2016/09/08 Javascript
BootStrap modal模态弹窗使用小结
2016/10/26 Javascript
详解js的异步编程技术的方法
2017/02/09 Javascript
vue中引入第三方字体文件的方法示例
2018/12/17 Javascript
解决vue项目本地启动时无法携带cookie的问题
2021/02/06 Vue.js
[17:45]DOTA2 HEROES教学视频教你分分钟做大人-军团指挥官
2014/06/11 DOTA
python概率计算器实例分析
2015/03/25 Python
tensorflow实现KNN识别MNIST
2018/03/12 Python
基于Django框架利用Ajax实现点赞功能实例代码
2018/08/19 Python
Python如何使用argparse模块处理命令行参数
2019/12/11 Python
学会python自动收发邮件 代替你问候女友
2020/05/20 Python
使用keras根据层名称来初始化网络
2020/05/21 Python
Keras构建神经网络踩坑(解决model.predict预测值全为0.0的问题)
2020/07/07 Python
python 制作磁力搜索工具
2021/03/04 Python
凯撒娱乐:Caesars Entertainment
2018/02/23 全球购物
2014年庆元旦活动方案
2014/02/15 职场文书
大学共青团员个人自我评价
2014/04/16 职场文书
祖国在我心中演讲稿(小学生)
2014/09/23 职场文书
学校实习推荐信
2015/03/27 职场文书
合作协议书格式范本
2016/03/21 职场文书
Python机器学习之基础概述
2021/05/19 Python
分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了
2021/05/21 Redis