| 订阅 | 在线投稿
分享
 
 
当前位置: 王朝网络 >> php >> 用PHP实现POP3邮件的收取(二)
 

用PHP实现POP3邮件的收取(二)

2008-12-23 08:12:45 编辑來源:互联网 繁體版 评论
 
 
  用PHP实现POP3收取邮件的类

  现在让我们来用PHP实现一个通过POP3协议收取信件的类吧,这个类中所用到的一些sock操作的函数,不另做特殊说明,请参考php的有关资料。通过这个实例,相信你也会和我一样,感觉到PHP中对于sock操作的灵活、方便和功能的强大。

  首先,我们来说明一下这个类中需要用到的一些内部成员变量:(这些变量应该都是对外封闭的,可是由于php对类的成员变量没有private与publice之类的分别,只好就这么直接定义了。这是PHP的一个令人遗憾的地方。)

  1.成员变量说明

  class pop3

  {

  var $hostname=""; // POP主机名

  var $port=110; // 主机的POP3端口,一般是110号端口

  var $timeout=5;// 连接主机的最大超时时间

  var $connection=0; // 保存与主机的连接

  var $state="DISCONNECTED"; // 保存当前的状态

  var $debug=0;// 做为标识,是否在调试状态,是的话,输出调试信息

  var $err_str='';// 如果出错,这里保存错误信息

  var $err_no;//如果出错,这里保存错误号码

  var $resp; // 临时保存服务器的响应信息

  var $apop; // 指示需要使用加密方式进行密码验证,一般服务器不需要

  var $messages; //邮件数

  var $size; //各邮件的总大小

  var $mail_list; // 一个数组,保存各个邮件的大小及其在邮件服务器上序号

  var $head=array(); // 邮件头的内容,数组

  var $body=array(); // 邮件体的内容,数组;

  2.当然,这其中的有些变量,仅通过这样一个简单的说明并不能完全了解如何使用,下面我就逐个来说明这个类实现中的一些主要方法:

  Function pop3($server="192.100.100.1",$port=110,$time_out=5)

  {$this->hostname=$server;

  $this->port=$port;

  $this->timeout=$time_out;

  return true;

  }

  熟悉面向对象编程的朋友一看就会知道,这是这个类的构造函数,在初始化这个类时,可以给出这几个最基本的参数:pop3服务器的地址,端口号,及连接服务器时的最大超时时间。一般来说,只需要给出POP3服务器的地址就行了。

  Function open()

  {

  if($this->hostname=="")

  {$this->err_str="无效的主机名!!";

  return false;

  }

  if ($this->debug) echo "正在打开$this->hostname,$this->port,&$err_no, &$err_str, $this->timeout<BR>";

  if (!$this->connection=fsockopen($this->hostname,$this->port,&$err_no, &$err_str, $this->timeout))

  {

  $this->err_str="连接到POP服务器失败,错误信息:".$err_str."错误号:".$err_no;

  return false;

  }

  else

  {

  $this->getresp();

  if($this->debug)

   $this->outdebug($this->resp);

  if (substr($this->resp,0,3)!="+OK")

  {$this->err_str="服务器返回无效的信息:".$this->resp."请检查POP服务器是否正确";

  return false;

  }

  $this->state="AUTHORIZATION";

  return true;

  }

  }

  该方法不需要任何参数就可建立与POP3服务器的sock连接。该方法又用到了另一个类中的方法$this->getresp();下面是这个方法的声明:

  Function getresp()

  {

  for($this->resp="";;)

  {

  if(feof($this->connection))

  return false;

  $this->resp.=fgets($this->connection,100);

  $length=strlen($this->resp);

  if($length>=2 && substr($this->resp,$length-2,2)=="\r\n")

  {

   $this->resp=strtok($this->resp,"\r\n");

  return true;

  }

  }

  }

  这个方法取得服务器端的返回信息并进行简单的处理:去掉最后的回车换行符,将返回信息保存在resp这个内部变量中。这个方法在后面的多个操作中都将用到。另外,还有个小方法也在后面的多个操作中用到:

  Function outdebug($message)

  {

  echo htmlspecialchars($message)."<br>\n";

  }

  它的作用就是把调试信息$message显示出来,并把一些特殊字符进行转换以及在行尾加上<br>标签,这样是为了使其输出的调试信息便于阅读和分析。

  建立起与服务器的sock连接之后,就要给服务器发送相关的命令了(请参见上面的与服务器对话的过程)从上面对POP对话的分析可以看到,每次都是发送一条命令,然后服务器给予一定的回应,如果命令的执行是对的,回应一般是以+OK开头,后面是一些描述信息,所以,我们可以做一个通过发送命令的方法:

  Function command($command,$return_lenth=1,$return_code='+')

  {

  if ($this->connection==0)

  {

  $this->err_str="没有连接到任何服务器,请检查网络连接";

  return false;

  }

  if ($this->debug)

  $this->outdebug(">>> $command");

  if (!fputs($this->connection,"$command\r\n"))

  {

  $this->err_str="无法发送命令".$command;

  return false;

  }

  else

  {

  $this->getresp();

  if($this->debug)

   $this->outdebug($this->resp);

  if (substr($this->resp,0,$return_lenth)!=$return_code)

  {

  $this->err_str=$command." 命令服务器返回无效:".$this->resp;

  return false;

  }

  else

  return true;

  }

  }

  这个方法可以接受三个参数: $command--> 发送给服务器的命令; $return_lenth,$return_code ,指定从服务器的返回中取多长的值做为命令返回的标识以及这个标识的正确值是什么。对于一般的pop操作来说,如果服务器的返回第一个字符为"+",则可以认为命令是正确执行了。也可以用前面提到过的三个字符"+OK"做为判断的标识。

  下面介绍的几个方法则可以按照前述收取信件的对话去理解,因为有关的内容已经在前面做了说明,因此下面的方法不做详细的说明,请参考其中的注释:

  Function Login($user,$password)//发送用户名及密码,登录到服务器

  {

  if($this->state!="AUTHORIZATION")

  {

  $this->err_str="还没有连接到服务器或状态不对";

  return false;

  }

  if (!$this->apop) //服务器是否采用APOP用户认证

  {

  if (!$this->command("USER $user",3,"+OK")) return false;

  if (!$this->command("PASS $password",3,"+OK")) return false;

  }

  else

  {

  //echo $this->resp=strtok($this->resp,"\r\n");

  if (!$this->command("APOP $user ".md5($this->greeting.$password),3,"+OK")) return false;

  }

  $this->state="TRANSACTION"; // 用户认证通过,进入传送模式

  return true;

  }

  Function stat() // 对应着stat命令,取得总的邮件数与总的大小

  {

  if($this->state!="TRANSACTION")

  {

  $this->err_str="还没有连接到服务器或没有成功登录";

  return false;

  }

  if (!$this->command("STAT",3,"+OK"))

  return false;

  else

  {

  $this->resp=strtok($this->resp," ");

  $this->messages=strtok(" "); // 取得邮件总数

  $this->size=strtok(" "); //取得总的字节大小

  return true;

  }

  }

  Function listmail($mess=null,$uni_id=null) //对应的是LIST命令,取得每个邮件的大小及序号。一般来说用到的是List命令,如果指定了$uni_id ,则使用UIDL命令,返回的是每个邮件的标识符,事实上,这个标识符一般是没有什么用的。取得的各个邮件的大小返回到类的内部变量mail_list这个二维数组里。

  {

  if($this->state!="TRANSACTION")

  {

  $this->err_str="还没有连接到服务器或没有成功登录";

  return false;

  }

  if ($uni_id)

  $command="UIDL ";

  else

  $command="LIST ";

  if ($mess)

  $command.=$mess;

  if (!$this->command($command,3,"+OK"))

  {

  //echo $this->err_str;

  return false;

  }

  else

  {

  $i=0;

  $this->mail_list=array();

  $this->getresp();

  while ($this->resp!=".")

  { $i++;

  if ($this->debug)

  {

  $this->outdebug($this->resp);

  }

  if ($uni_id)

  {

  $this->mail_list[$i][num]=strtok($this->resp," ");

  $this->mail_list[$i][size]=strtok(" ");

  }

  else

  {

  $this->mail_list[$i]["num"]=intval(strtok($this->resp," "));

  $this->mail_list[$i]["size"]=intval(strtok(" "));

  }

  $this->getresp();

  }

  return true;

  }

  }

  function getmail($num=1,$line=-1)// 取得邮件的内容,$num是邮件的序号,$line是指定共取得正文的多少行。有些时候,如邮件比较大而我们只想先查看邮件的主题时是必须指定行数的。默认值$line=-1,即取回所有的邮件内容,取得的内容存放到内部变量$head,$body两个数组里,数组里的每一个元素对应的是邮件源代码的一行。

  {

  if($this->state!="TRANSACTION")

  {

  $this->err_str="不能收取信件,还没有连接到服务器或没有成功登录";

  return false;

  }

  if ($line<0)

  $command="RETR $num";

  else

  $command="TOP $num $line";

  if (!$this->command("$command",3,"+OK"))

  return false;

  else

  {

  $this->getresp();

  $is_head=true;

  while ($this->resp!=".") // . 号是邮件结束的标识

  {

  if ($this->debug)

  $this->outdebug($this->resp);

  if (substr($this->resp,0,1)==".")

  $this->resp=substr($this->resp,1,strlen($this->resp)-1);

  if (trim($this->resp)=="") // 邮件头与正文部分的是一个空行

  $is_head=false;

  if ($is_head)

  $this->head[]=$this->resp;

  else

  $this->body[]=$this->resp;

  $this->getresp();

  }

  return true;

  }

  } // end function

  function dele($num) // 删除指定序号的邮件,$num 是服务器上的邮件序号

  {

  if($this->state!="TRANSACTION")

  {

  $this->err_str="不能删除远程信件,还没有连接到服务器或没有成功登录";

  return false;

  }

  if (!$num)

  {

  $this->err_str="删除的参数不对";

  return false;

  }

  if ($this->command("DELE $num ",3,"+OK"))

  return true;

  else

  return false;

  }

  通过以上几个方法,我们已经可以实现邮件的查看、收取、删除的操作,不过别忘了最后要退出,并关闭与服务器的连接,调用下面的这个方法:

  Function Close()

  {

  if($this->connection!=0)

  {

  if($this->state=="TRANSACTION")

  $this->command("QUIT",3,"+OK");

  fclose($this->connection);

  $this->connection=0;

  $this->state="DISCONNECTED";

  }

  }
 
 
 
 
上一篇《用PHP实现POP3邮件的收取(三)》
下一篇《用PHP实现POP3邮件的收取(一)》
 
 
 
 
 
 
日版宠物情人插曲《Winding Road》歌词

日版宠物情人2017的插曲,很带节奏感,日语的,女生唱的。 最后听见是在第8集的时候女主手割伤了,然后男主用嘴帮她吸了一下,插曲就出来了。 歌手:Def...

兄弟共妻,我成了他们夜里的美食

老钟家的两个儿子很特别,就是跟其他的人不太一样,魔一般的执着。兄弟俩都到了要结婚的年龄了,不管自家老爹怎么磨破嘴皮子,兄弟俩说不娶就不娶,老父母为兄弟两操碎了心...

如何磨出破洞牛仔裤?牛仔裤怎么剪破洞?

把牛仔裤磨出有线的破洞 1、具体工具就是磨脚石,下面垫一个硬物,然后用磨脚石一直磨一直磨,到把那块磨薄了,用手撕开就好了。出来的洞啊很自然的。需要猫须的话调几...

我就是扫描下图得到了敬业福和爱国福

先来看下敬业福和爱国福 今年春节,支付宝再次推出了“五福红包”活动,表示要“把欠大家的敬业福都还给大家”。 今天该活动正式启动,和去年一样,需要收集“五福”...

冰箱异味产生的原因和臭味去除的方法

有时候我们打开冰箱就会闻到一股异味,冰箱里的这种异味是因为一些物质发出的气味的混合体,闻起来让人恶心。 产生这些异味的主要原因有以下几点。 1、很多人有这种习...

 
 
 
用PHP实现POP3收取邮件的类   现在让我们来用PHP实现一个通过POP3协议收取信件的类吧,这个类中所用到的一些sock操作的函数,不另做特殊说明,请参考php的有关资料。通过这个实例,相信你也会和我一样,感觉到PHP中对于sock操作的灵活、方便和功能的强大。   首先,我们来说明一下这个类中需要用到的一些内部成员变量:(这些变量应该都是对外封闭的,可是由于php对类的成员变量没有private与publice之类的分别,只好就这么直接定义了。这是PHP的一个令人遗憾的地方。)      1.成员变量说明   class pop3   {       var $hostname=""; // POP主机名       var $port=110; // 主机的POP3端口,一般是110号端口    var $timeout=5;  // 连接主机的最大超时时间        var $connection=0; // 保存与主机的连接       var $state="DISCONNECTED"; // 保存当前的状态        var $debug=0;  // 做为标识,是否在调试状态,是的话,输出调试信息    var $err_str='';  // 如果出错,这里保存错误信息    var $err_no;   //如果出错,这里保存错误号码    var $resp; // 临时保存服务器的响应信息    var $apop; // 指示需要使用加密方式进行密码验证,一般服务器不需要    var $messages; // 邮件数    var $size; //各邮件的总大小    var $mail_list; // 一个数组,保存各个邮件的大小及其在邮件服务器上序号      var $head=array(); // 邮件头的内容,数组    var $body=array(); // 邮件体的内容,数组;      2.当然,这其中的有些变量,仅通过这样一个简单的说明并不能完全了解如何使用,下面我就逐个来说明这个类实现中的一些主要方法:   Function pop3($server="192.100.100.1",$port=110,$time_out=5)   {$this->hostname=$server;    $this->port=$port;    $this->timeout=$time_out;    return true;   }   熟悉面向对象编程的朋友一看就会知道,这是这个类的构造函数,在初始化这个类时,可以给出这几个最基本的参数:pop3服务器的地址,端口号,及连接服务器时的最大超时时间。一般来说,只需要给出POP3服务器的地址就行了。   Function open()   {   if($this->hostname=="")     {$this->err_str="无效的主机名!!";    return false;    }     if ($this->debug) echo "正在打开 $this->hostname,$this->port,&$err_no, &$err_str, $this->timeout<BR>";   if (!$this->connection=fsockopen($this->hostname,$this->port,&$err_no, &$err_str, $this->timeout))    {    $this->err_str="连接到POP服务器失败,错误信息:".$err_str."错误号:".$err_no;    return false;    }    else    {    $this->getresp();    if($this->debug)               $this->outdebug($this->resp);    if (substr($this->resp,0,3)!="+OK")    {$this->err_str="服务器返回无效的信息:".$this->resp."请检查POP服务器是否正确";    return false;    }    $this->state="AUTHORIZATION";    return true;    }   }   该方法不需要任何参数就可建立与POP3服务器的sock连接。该方法又用到了另一个类中的方法$this->getresp();下面是这个方法的声明:   Function getresp()    {    for($this->resp="";;)      {          if(feof($this->connection))                return false;            $this->resp.=fgets($this->connection,100);            $length=strlen($this->resp);            if($length>=2 && substr($this->resp,$length-2,2)=="\r\n")            {             $this->resp=strtok($this->resp,"\r\n");    return true;            }           }       }   这个方法取得服务器端的返回信息并进行简单的处理:去掉最后的回车换行符,将返回信息保存在resp这个内部变量中。这个方法在后面的多个操作中都将用到。另外,还有个小方法也在后面的多个操作中用到:   Function outdebug($message)   {    echo htmlspecialchars($message)."<br>\n";   }   它的作用就是把调试信息$message显示出来,并把一些特殊字符进行转换以及在行尾加上<br>标签,这样是为了使其输出的调试信息便于阅读和分析。   建立起与服务器的sock连接之后,就要给服务器发送相关的命令了(请参见上面的与服务器对话的过程)从上面对 POP对话的分析可以看到,每次都是发送一条命令,然后服务器给予一定的回应,如果命令的执行是对的,回应一般是以+OK开头,后面是一些描述信息,所以,我们可以做一个通过发送命令的方法:   Function command($command,$return_lenth=1,$return_code='+')   {    if ($this->connection==0)    {    $this->err_str="没有连接到任何服务器,请检查网络连接";    return false;    }    if ($this->debug)    $this->outdebug(">>> $command");    if (!fputs($this->connection,"$command\r\n"))    {    $this->err_str="无法发送命令".$command;    return false;    }    else    {    $this->getresp();    if($this->debug)       $this->outdebug($this->resp);    if (substr($this->resp,0,$return_lenth)!=$return_code)    {    $this->err_str=$command." 命令服务器返回无效:".$this->resp;    return false;    }     else    return true;     }   }   这个方法可以接受三个参数: $command--> 发送给服务器的命令; $return_lenth,$return_code ,指定从服务器的返回中取多长的值做为命令返回的标识以及这个标识的正确值是什么。对于一般的pop操作来说,如果服务器的返回第一个字符为"+",则可以认为命令是正确执行了。也可以用前面提到过的三个字符"+OK"做为判断的标识。   下面介绍的几个方法则可以按照前述收取信件的对话去理解,因为有关的内容已经在前面做了说明,因此下面的方法不做详细的说明,请参考其中的注释:   Function Login($user,$password) //发送用户名及密码,登录到服务器   {   if($this->state!="AUTHORIZATION")    {    $this->err_str="还没有连接到服务器或状态不对";    return false;    }   if (!$this->apop) //服务器是否采用APOP用户认证    {    if (!$this->command("USER $user",3,"+OK")) return false;    if (!$this->command("PASS $password",3,"+OK")) return false;    }   else    {    //echo $this->resp=strtok($this->resp,"\r\n");    if (!$this->command("APOP $user ".md5($this->greeting.$password),3,"+OK")) return false;    }   $this->state="TRANSACTION"; // 用户认证通过,进入传送模式   return true;   }      Function stat() // 对应着stat命令,取得总的邮件数与总的大小   {   if($this->state!="TRANSACTION")    {    $this->err_str="还没有连接到服务器或没有成功登录";    return false;    }   if (!$this->command("STAT",3,"+OK"))    return false;    else    {    $this->resp=strtok($this->resp," ");    $this->messages=strtok(" "); // 取得邮件总数    $this->size=strtok(" "); //取得总的字节大小    return true;    }   }   Function listmail($mess=null,$uni_id=null) //对应的是LIST命令,取得每个邮件的大小及序号。一般来说用到的是List命令,如果指定了$uni_id ,则使用UIDL命令,返回的是每个邮件的标识符,事实上,这个标识符一般是没有什么用的。取得的各个邮件的大小返回到类的内部变量mail_list这个二维数组里。   {   if($this->state!="TRANSACTION")    {    $this->err_str="还没有连接到服务器或没有成功登录";    return false;    }   if ($uni_id)    $command="UIDL ";    else    $command="LIST ";   if ($mess)    $command.=$mess;     if (!$this->command($command,3,"+OK"))    {    //echo $this->err_str;    return false;    }    else    {    $i=0;    $this->mail_list=array();    $this->getresp();    while ($this->resp!=".")    { $i++;    if ($this->debug)    {    $this->outdebug($this->resp);    }    if ($uni_id)    {    $this->mail_list[$i][num]=strtok($this->resp," ");    $this->mail_list[$i][size]=strtok(" ");    }    else    {    $this->mail_list[$i]["num"]=intval(strtok($this->resp," "));    $this->mail_list[$i]["size"]=intval(strtok(" "));    }    $this->getresp();    }    return true;    }   }   function getmail($num=1,$line=-1) // 取得邮件的内容,$num是邮件的序号,$line是指定共取得正文的多少行。有些时候,如邮件比较大而我们只想先查看邮件的主题时是必须指定行数的。默认值$line=-1,即取回所有的邮件内容,取得的内容存放到内部变量$head,$body两个数组里,数组里的每一个元素对应的是邮件源代码的一行。   {   if($this->state!="TRANSACTION")    {    $this->err_str="不能收取信件,还没有连接到服务器或没有成功登录";    return false;    }   if ($line<0)    $command="RETR $num";   else    $command="TOP $num $line";      if (!$this->command("$command",3,"+OK"))    return false;    else    {    $this->getresp();    $is_head=true;    while ($this->resp!=".") // . 号是邮件结束的标识    {    if ($this->debug)    $this->outdebug($this->resp);    if (substr($this->resp,0,1)==".")    $this->resp=substr($this->resp,1,strlen($this->resp)-1);    if (trim($this->resp)=="") // 邮件头与正文部分的是一个空行    $is_head=false;    if ($is_head)    $this->head[]=$this->resp;    else    $this->body[]=$this->resp;    $this->getresp();    }    return true;    }   } // end function      function dele($num) // 删除指定序号的邮件,$num 是服务器上的邮件序号   {    if($this->state!="TRANSACTION")    {    $this->err_str="不能删除远程信件,还没有连接到服务器或没有成功登录";    return false;    }    if (!$num)    {    $this->err_str="删除的参数不对";    return false;    }    if ($this->command("DELE $num ",3,"+OK"))    return true;    else    return false;   }   通过以上几个方法,我们已经可以实现邮件的查看、收取、删除的操作,不过别忘了最后要退出,并关闭与服务器的连接,调用下面的这个方法:   Function Close()   {   if($this->connection!=0)    {    if($this->state=="TRANSACTION")    $this->command("QUIT",3,"+OK");    fclose($this->connection);      $this->connection=0;    $this->state="DISCONNECTED";    }   }
󰈣󰈤
 
 
 
  免责声明:本文仅代表作者个人观点,与王朝网络无关。王朝网络登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
时尚秀气模特裴裴(8)
时尚秀气模特裴裴(7)
时尚秀气模特裴裴(6)
时尚秀气模特裴裴(5)
白墙黑瓦
广州东郊[原创]
八美至丹巴的东谷天然盆景
不一样的
 
>>返回首页<<
 
 
 为你推荐
 
 
 
 转载本文
 UBB代码 HTML代码
复制到剪贴板...
 
 热帖排行
 
 
 
 
©2005- 王朝网络 版权所有