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 相关文章推荐
Uchome1.2 1.5 代码学习 common.php
Apr 24 PHP
PHP 读取和修改大文件的某行内容的代码
Oct 30 PHP
php将数据库导出成excel的方法
May 07 PHP
PHP中获取文件扩展名的N种方法小结
Feb 27 PHP
让codeigniter与swfupload整合的最佳解决方案
Jun 12 PHP
PHP采集类snoopy详细介绍(snoopy使用教程)
Jun 19 PHP
PHP中使用register_shutdown_function函数截获fatal error示例
Apr 21 PHP
PHP实现递归复制整个文件夹的类实例
Aug 03 PHP
Zend Framework实现留言本分页功能(附demo源码下载)
Mar 22 PHP
smarty自定义函数用法示例
May 20 PHP
PHP中使用foreach()遍历二维数组的简单实例
Jun 13 PHP
session 加入redis的实现代码
Jul 15 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
如何使用FireFox插件FirePHP调试PHP
2013/07/23 PHP
PHP应用跨时区功能的实现方法
2019/03/21 PHP
用htc组件制作windows选项卡
2007/01/13 Javascript
HTML-CSS群中单选引发的“事件”
2007/03/05 Javascript
JS控制图片等比例缩放的示例代码
2013/12/24 Javascript
node.js中的path.delimiter方法使用说明
2014/12/09 Javascript
js实现绿白相间竖向网页百叶窗动画切换效果
2015/03/02 Javascript
浅谈js中的闭包
2015/03/16 Javascript
javascript实现的左右无缝滚动效果
2016/09/19 Javascript
bootstrap table分页模板和获取表中的ID方法
2017/01/10 Javascript
jQuery实现倒计时重新发送短信验证码功能示例
2017/01/12 Javascript
详解vue mixins和extends的巧妙用法
2017/12/20 Javascript
详解react-redux插件入门
2018/04/19 Javascript
Vue 使用 Mint UI 实现左滑删除效果CellSwipe
2018/04/27 Javascript
用Python制作简单的朴素基数估计器的教程
2015/04/01 Python
Python中的Numeric包和Numarray包使用教程
2015/04/13 Python
小米5s微信跳一跳小程序python源码
2018/01/08 Python
Python+PyQT5的子线程更新UI界面的实例
2019/06/14 Python
使用Filter过滤python中的日志输出的实现方法
2019/07/17 Python
Python一行代码解决矩阵旋转的问题
2019/11/30 Python
基于Python爬取爱奇艺资源过程解析
2020/03/02 Python
python实现斗地主分牌洗牌
2020/06/22 Python
如何把python项目部署到linux服务器
2020/08/26 Python
协程Python 中实现多任务耗资源最小的方式
2020/10/19 Python
机关道德讲堂实施方案
2014/03/15 职场文书
初中学校军训方案
2014/05/09 职场文书
校庆标语集锦
2014/06/25 职场文书
2015年毕业生自我鉴定模板
2014/09/19 职场文书
2014年变电站工作总结
2014/12/19 职场文书
小学教师节活动总结
2015/03/20 职场文书
2015年医生个人工作总结
2015/04/25 职场文书
详解overflow:hidden的作用(溢出隐藏、清除浮动、解决外边距塌陷)
2021/07/01 HTML / CSS
quickjs 封装 JavaScript 沙箱详情
2021/11/02 Javascript
Sql Server之数据类型详解
2022/02/28 SQL Server
详解Alibaba Java诊断工具Arthas查看Dubbo动态代理类
2022/04/08 Java/Android
docker 制作mysql镜像并自动安装
2022/05/20 Servers