PHP的一个完整SMTP类(解决邮件服务器需要验证时的问题)

 更新时间:2016年11月25日 17:03  点击:1719
smtp.php
<?php
class smtp
{
/* Public Variables */
var $smtp_port;
var $time_out;
var $host_name;
var $log_file;
var $relay_host;
var $debug;
var $auth;
var $user;
var $pass;
/* Private Variables */
var $sock;
/* Constractor */
function smtp($relay_host = "", $smtp_port = 25,$auth = false,$user,$pass)
{
$this->debug = FALSE;
$this->smtp_port = $smtp_port;
$this->relay_host = $relay_host;
$this->time_out = 30; //is used in fsockopen()
#
$this->auth = $auth;//auth
$this->user = $user;
$this->pass = $pass;
#
$this->host_name = "localhost"; //is used in HELO command
$this->log_file = "";
 
$this->sock = FALSE;
}
/* Main Function */
function sendmail($to, $from, $subject = "", $body = "", $mailtype, $cc = "", $bcc = "", $additional_headers = "")
{
$mail_from = $this->get_address($this->strip_comment($from));
$body = ereg_replace("(^|( ))(.)", "1.3", $body);
$header .= "MIME-Version:1.0 ";
if($mailtype=="HTML"){
$header .= "Content-Type:text/html ";
}
$header .= "To: ".$to." ";
if ($cc != "") {
$header .= "Cc: ".$cc." ";
}
$header .= "From: $from<".$from."> ";
$header .= "Subject: ".$subject." ";
$header .= $additional_headers;
$header .= "Date: ".date("r")." ";
$header .= "X-Mailer:By Redhat (PHP/".phpversion().") ";
list($msec, $sec) = explode(" ", microtime());
$header .= "Message-ID: <".date("YmdHis", $sec).".".($msec*1000000).".".$mail_from."> ";
$TO = explode(",", $this->strip_comment($to));
if ($cc != "") {
$TO = array_merge($TO, explode(",", $this->strip_comment($cc)));
}
if ($bcc != "") {
$TO = array_merge($TO, explode(",", $this->strip_comment($bcc)));
}
$sent = TRUE;
foreach ($TO as $rcpt_to) {
实现 MIME 解码的类
(作者:陈俊清 2000年10月24日 15:11)
  一个实现 MIME 解码的类
  该类实现解码的方法是 decode($head=null,$body=null,$content_num=-1),为了处理上的方便,要求输入的是两个字符数组,在我们的上篇中,所用到的POP类所收取得到的就是两个这样的数组,一个是邮件头内容,一个是邮件的正文内容。限于篇幅,不对其做详细的说明,其实现思想跟本文上篇中所介绍的POP类类似。请参考其中的注释。
  该类中用到了大量的正则表达式的操作,对此不熟悉的读者,请参考正则表达式的有关资料。
  class decode_mail
  {
  var $from_name;var $to_name;var $mail_time;var $from_mail;var $to_mail;
  var $reply_to;var $cc_to;var $subject;
  // 解码后的邮件头部分的信息:
  var $body;
  // 解码后得到的正文数据,为一个数组。
  var $body_type; // 正文类型
  var $tem_num=0;
  var $get_content_num=0;
  var $body_temp=array();
  var $body_code_type;
  var $boundary;
  // 以上是一些方法中用到的一些全局性的临时变量,由于 PHP不能做到良好的封装,所以只能放在这里定义
  var $err_str; // 错误信息
  var $debug=0; // 调试标记
  var $month_num=array("Jan"=>1,"Feb"=>2,"Mar"=>3,"Apr"=>4,"May"=>5,"Jun"=>6,"Jul"=>7,
  "Aug"=>8,"Sep"=>9,"Oct"=>10,"Nov"=>11,"Dec"=>12); // 把英文月份转换成数字表示的月份
  function decode($head=null,$body=null,$content_num=-1) // 调用的主方法,$head 与 $body 是两个数组,$content_num 表示的是当正文有多个部分的时候,只取出指定部分的内容以提高效率,默认为 -1 ,表示解码全部内容,如果解码成功,该 方法返回 true
  {
   if (!$head and !$body)
   {
   $this->err_str="没有指定邮件的头与内容!!";
   return false;
   }
  if (gettype($head)=="array")
   {
   $have_decode=true;
   $this->decode_head($head);
如果你无法在服务器上安装IMAIL,那只能通过socket来发送邮件。但是如果你幸运的话,也可以用163/sina的
smtp服务。
例程如下(原程序由马毅兄提供):
<HTML>
<HEAD>
<TITLE>Mail Form anywhere </TITLE>
</HEAD>
<BODY>
<?
if($sendit)
{
$smtpserver="202.110.200.242" ;        //将此处设为IMAIL的IP
echo "<pre>" ;
$fp = fsockopen($smtpserver, 25, &$errno, &$errstr, 10) ; //连接smtp服务器,端口25
if(!$fp) die("wrong open smtp SERVER") ;
$hostreplay=fgets($fp,128);
//if (!strstr($hostreplay,"220")) die(" can n't receive the 220 answer ") ;
$smailname=strstr(ltrim($hostreplay),"220 ") ;
$smailname=substr($smailname,0,strpos($smailname,".")) ;
//echo " smailname:$smailname " ;
fputs($fp,"$smailname ") ;
$hostreplay=fgets($fp,128);
//if (!strstr($hostreplay,"250")) die(" can n't receive the 250 answer ") ;
fputs($fp,"MAIL FROM: ") ;
$hostreplay=fgets($fp,128) ;
if (!strstr($hostreplay,"250")) {
fputs($fp,"MAIL FROM: root ") ;
$hostreplay=fgets($fp,128) ;
if (!strstr($hostreplay,"250")) {
fputs($fp,"MAIL FROM: root@263.net ") ;
echo($hostreplay=fgets($fp,128)) ;
if (!strstr($hostreplay,"250")) {
fputs($fp,"MAIL FROM: $from_address ") ;
$hostreplay=fgets($fp,128) ;
if (!strstr($hostreplay,"250")) die(" can n't receive the 250 answer ") ;
};
};
};
fputs($fp,"RCPT TO: $to_address ") ;
$hostreplay=fgets($fp,128);
if (!strstr($hostreplay,"250")) {
fputs($fp,"RCPT TO: $mailname ") ;
$hostreplay=fgets($fp,128) ;
if (!strstr($hostreplay,"250")) echo(" can n't receive the 354 answer") ;
MIME 编码方式简介
(作者:陈俊清 2000年10月24日 15:09)
  MIME 编码方式简介
  Subject: =?gb2312?B?xOO6w6Oh?=
  这里是邮件的主题,可是因为编码了,我们看不出是什么内容,其原来的文本是:“你好!”我们先看看 MIME 编码的两种方法。
  对邮件进行编码最初的原因是因为 Internet 上的很多网关不能正确传输8 bit 内码的字符,比如汉字等。编码的原理就是把 8 bit 的内容转换成 7 bit 的形式以能正确传输,在接收方收到之后,再将其还原成 8 bit 的内容。
  MIME 是“多用途网际邮件扩充协议”的缩写,在 MIME 协议之前,邮件的编码曾经有过 UUENCODE 等编码方式 ,但是由于 MIME 协议算法简单,并且易于扩展,现在已经成为邮件编码方式的主流,不仅是用来传输 8 bit 的字符,也可以用来传送二进制的文件 ,如邮件附件中的图像、音频等信息,而且扩展了很多基于MIME 的应用。从编码方式来说,MIME 定义了两种编码方法Base64与QP(Quote-Printable) :
  Base 64 是一种通用的方法,其原理很简单,就是把三个Byte的数据用 4 个Byte表示,这样,这四个Byte 中,实际用到的都只有前面6 bit,这样就不存在只能传输 7bit 的字符的问题了。Base 64的缩写一般是“B”,像这封信中的Subject 就是用的 Base64 编码。
  另一种方法是QP(Quote-Printable) 方法,通常缩写为“Q”方法,其原理是把一个 8 bit 的字符用两个16进制数值表示,然后在前面加“=”。所以我们看到经过QP编码后的文件通常是这个样子:=B3=C2=BF=A1=C7=E5=A3=AC=C4=FA=BA=C3=A3=A1。
  在 PHP 里,系统有两个函数可以很方便地实现解码:base64_decode()与quoted_printable_decode(),前者可用于base64 编码的解码,后者是用于 QP 编码方法的解码。
  现在我们再来看看Subject: =?gb2312?B?xOO6w6Oh?= 这一主题的内容,这不是一段完整的编码,只有部分是编码了的,这个部分用 =? ?= 两个标记括起来,=? 后面说明的是这段文字的字符集是 GB2312 ,然后一个 ? 后面的一个 B 表示的是用的 Base64 编码。通过这段分析,我们来看一下这个 MIME 解码的函数:(该函数由 PHPX.COM 站长 Sadly 提供,本人将其放入一个类中,并做了少量的修改,在此致谢)
  function decode_mime($string) {
   $pos = strpos($string, '=?');
   if (!is_int($pos)) {
     return $string;
   }
<?
* 名称:用Socket发送电子邮件
* 描述:本类实现了直接使用需要验证的SMTP服务器直接发送邮件,参考文章《用Socket发送电子邮件》作者:limodou
* 此文章比较早,他是用不用验证SMTP服务器发送邮件,现在基本上SMTP服务器都需要验证了,所以这个文章里的类
意义也不是很大!同时参考了[RFC 1869]和PHP手册!!和上文还有不同的是我用的不是fsockopen()函数
具体你自己看吧!!我刚刚测试通过了,很爽!!
其实把这个类再改写一下就可以直接发送带附件的邮件了,期待。。。我过几天给大家写出来!
我刚刚调试通过,如果你不恶意去捉弄这个程序,他还是很听话的,过些日子我会对他完善加上发送附件的功能!!
即使你的虚拟主机不支持MAIL函数,现在也不怕了!快快试试这个吧!
请尊重别人的劳动成功,请保留此版权信息,谢谢!
作者:小露珠3.3 ,欢迎和我联系交流PHP QQ6550382
MAIL:cleverzhang@tom.com
*/
set_time_limit(120);
class smtp_mail
{
var $host; //主机
var $port; //端口 一般为25
var $user; //SMTP认证的帐号
var $pass; //认证密码
var $debug = false; //是否显示和服务器会话信息?
var $conn;
var $result_str; //结果
var $in; //客户机发送的命令
var $from; //源信箱
var $to; //目标信箱
var $subject; //主题
var $body; //内容
function smtp_mail($host,$port,$user,$pass,$debug=false)
{
$this->host = $host;
$this->port = $port;
$this->user = base64_encode($user);
$this->pass = base64_encode($pass);
$this->debug = $debug;
$this->socket = socket_create (AF_INET, SOCK_STREAM, SOL_TCP); //具体用法请参考手册
if($this->socket)
{
$this->result_str = "创建SOCKET:".socket_strerror(socket_last_error());
$this->debug_show($this->result_str);
}
else
{
exit("初始化失败,请检查您的网络连接和参数");
[!--infotagslink--]

相关文章

  • Django def clean()函数对表单中的数据进行验证操作

    这篇文章主要介绍了Django def clean()函数对表单中的数据进行验证操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-09
  • 分享一段php获取linux服务器状态的代码

    简单的php获取linux服务器状态的代码,不多说-直接上函数:复制代码 代码如下:function get_used_status(){ $fp = popen('top -b -n 2 | grep -E "^(Cpu|Mem|Tasks)"',"r");//获取某一时刻系统cpu和内存使用情况 $rs =...2014-05-31
  • Springboot+TCP监听服务器搭建过程图解

    这篇文章主要介绍了Springboot+TCP监听服务器搭建过程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-10-28
  • php邮件发送的两种方式

    这篇文章研究的主要内容就是使用PHP来发送电子邮件,总结为以下两种方法:一、使用PHP内置的mail()函数<&#63;php $to = "test@163.com"; //收件人 $subject = "Test"; //主题 $message = "This is a test mail!"; //正文...2015-10-30
  • 服务器 UDP端口占用几千个的解决办法

    前一段时间使用NetStat命令查看服务器端口时,发现服务器udp端口开放了好多,最少在1000个以上,当时事情比较多,没有管它,今天终于有点时间,仔细检查了一下,排除了这个问题. ...2016-01-27
  • PHP连接公司内部服务器的MYSQL数据库的简单实例

    “主机,用户名,密码”得到连接、“数据库,sql,连接”得到结果,最后是结果的处理显示。当然,数据库连接是扩展库为我们完成的,我们能做的仅仅是处理结果而已。...2013-09-29
  • c# 实现发送邮件的功能

    这篇文章主要介绍了c# 如何实现发送邮件的功能,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-07
  • Nest.js 授权验证的方法示例

    这篇文章主要介绍了Nest.js 授权验证的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-22
  • 解决HttpPost+json请求---服务器中文乱码及其他问题

    这篇文章主要介绍了解决HttpPost+json请求---服务器中文乱码及其他问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-22
  • el-table树形表格表单验证(列表生成序号)

    这篇文章主要介绍了el-table树形表格表单验证(列表生成序号),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-01
  • selenium 反爬虫之跳过淘宝滑块验证功能的实现代码

    这篇文章主要介绍了selenium 反爬虫之跳过淘宝滑块验证功能,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-08-27
  • JavaScript实现密码框输入验证

    这篇文章主要为大家详细介绍了JavaScript实现密码框输入验证,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-10-01
  • php邮件发送的两种方式

    这篇文章研究的主要内容就是使用PHP来发送电子邮件,总结为以下两种方法:一、使用PHP内置的mail()函数<&#63;php $to = "test@163.com"; //收件人 $subject = "Test"; //主题 $message = "This is a test mail!"; //正文...2015-10-30
  • vue实现表单验证小功能

    这篇文章主要为大家详细介绍了vue实现表单验证小功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-29
  • js canvas实现滑块验证

    这篇文章主要为大家详细介绍了js canvas实现滑块验证,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-03-14
  • Hyper-V尝试连接到服务器出错无效类的解决方法

    这篇文章主要介绍了Hyper-V尝试连接到服务器出错无效类的解决方法,需要的朋友可以参考下...2016-09-28
  • c#使用netmail方式发送邮件示例

    这篇文章主要介绍了c#使用netmail方式发送邮件的示例,大家参考使用吧...2020-06-25
  • vue element table中自定义一些input的验证操作

    这篇文章主要介绍了vue element table中自定义一些input的验证操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-18
  • JavaScript表单验证示例详解

    这篇文章主要为大家详细介绍了JavaScript表单验证示例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-10-04
  • mac使用Shell(终端)SSH连接远程服务器的方法

    这篇文章主要介绍了mac使用Shell(终端)SSH连接远程服务器的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-07-11